2023-08-26 19:41:00 +02:00
//! A library for interacting with one or multiple Spacebar-compatible APIs and Gateways.
//!
//! # About
//!Chorus is a Rust library that allows developers to interact with multiple Spacebar-compatible APIs and Gateways simultaneously. The library provides a simple and efficient way to communicate with these services, making it easier for developers to build applications that rely on them. Chorus is open-source and welcomes contributions from the community.
2023-08-28 12:27:38 +02:00
#![ doc(
html_logo_url = " https://raw.githubusercontent.com/polyphony-chat/design/main/branding/polyphony-chorus-round-8bit.png "
) ]
2023-06-19 10:27:32 +02:00
#![ allow(clippy::module_inception) ]
2023-08-28 12:27:38 +02:00
#![ deny(
missing_debug_implementations ,
clippy ::extra_unused_lifetimes ,
clippy ::from_over_into ,
clippy ::needless_borrow ,
clippy ::new_without_default ,
clippy ::useless_conversion
) ]
2023-11-13 15:26:46 +01:00
#[ cfg(all(feature = " rt " , feature = " rt_multi_thread " )) ]
compile_error! ( " feature \" rt \" and feature \" rt_multi_thread \" cannot be enabled at the same time " ) ;
2023-06-19 10:27:32 +02:00
2023-11-15 22:31:44 +01:00
#[ cfg(all(not(target_arch = " wasm32 " ), feature = " client " )) ]
2023-11-15 21:09:24 +01:00
pub type Gateway = DefaultGateway ;
2023-11-15 22:31:44 +01:00
#[ cfg(all(not(target_arch = " wasm32 " ), feature = " client " )) ]
2023-11-15 21:09:24 +01:00
pub type GatewayHandle = DefaultGatewayHandle ;
2023-11-15 20:56:58 +01:00
2023-11-15 21:09:24 +01:00
use gateway ::DefaultGateway ;
use gateway ::DefaultGatewayHandle ;
2023-06-11 13:52:31 +02:00
use url ::{ ParseError , Url } ;
2023-05-26 16:16:08 +02:00
#[ cfg(feature = " client " ) ]
2023-05-09 14:04:46 +02:00
pub mod api ;
pub mod errors ;
2023-05-26 16:16:08 +02:00
#[ cfg(feature = " client " ) ]
2023-05-09 14:04:46 +02:00
pub mod gateway ;
2023-05-26 16:16:08 +02:00
#[ cfg(feature = " client " ) ]
2023-05-09 14:04:46 +02:00
pub mod instance ;
2023-05-26 16:16:08 +02:00
#[ cfg(feature = " client " ) ]
2023-07-09 18:38:02 +02:00
pub mod ratelimiter ;
2023-05-25 21:11:08 +02:00
pub mod types ;
2023-05-26 16:16:08 +02:00
#[ cfg(feature = " client " ) ]
2023-05-09 14:04:46 +02:00
pub mod voice ;
2023-04-05 21:54:27 +02:00
2023-08-30 19:13:46 +02:00
#[ derive(Clone, Default, Debug, PartialEq, Eq, Hash) ]
2023-07-29 10:23:04 +02:00
/// A URLBundle bundles together the API-, Gateway- and CDN-URLs of a Spacebar instance.
///
2023-07-10 17:22:31 +02:00
/// # Notes
/// All the urls can be found on the /api/policies/instance/domains endpoint of a spacebar server
2023-06-20 02:59:18 +02:00
pub struct UrlBundle {
2023-07-10 17:22:31 +02:00
/// The api's url.
/// Ex: `https://old.server.spacebar.chat/api`
2023-04-05 21:54:27 +02:00
pub api : String ,
2023-07-10 17:22:31 +02:00
/// The gateway websocket url.
2023-07-29 10:23:04 +02:00
/// Note that because this is a websocket url, it will always start with `wss://` or `ws://`
2023-07-10 17:22:31 +02:00
/// Ex: `wss://gateway.old.server.spacebar.chat`
2023-04-05 21:54:27 +02:00
pub wss : String ,
2023-07-10 17:22:31 +02:00
/// The CDN's url.
/// Ex: `https://cdn.old.server.spacebar.chat`
2023-04-05 21:54:27 +02:00
pub cdn : String ,
}
2023-06-20 02:59:18 +02:00
impl UrlBundle {
2023-07-29 11:26:00 +02:00
/// Creates a new UrlBundle from the relevant urls.
2023-04-05 21:54:27 +02:00
pub fn new ( api : String , wss : String , cdn : String ) -> Self {
Self {
2023-06-20 02:59:18 +02:00
api : UrlBundle ::parse_url ( api ) ,
wss : UrlBundle ::parse_url ( wss ) ,
cdn : UrlBundle ::parse_url ( cdn ) ,
2023-04-05 21:54:27 +02:00
}
}
2023-07-29 10:23:04 +02:00
/// Parses a URL using the Url library and formats it in a standardized way.
/// If no protocol is given, HTTP (not HTTPS) is assumed.
///
/// # Examples:
2023-04-05 22:19:15 +02:00
/// ```rs
2023-04-05 21:54:27 +02:00
/// let url = parse_url("localhost:3000");
/// ```
/// `-> Outputs "http://localhost:3000".`
pub fn parse_url ( url : String ) -> String {
let url = match Url ::parse ( & url ) {
Ok ( url ) = > {
if url . scheme ( ) = = " localhost " {
2023-06-20 02:59:18 +02:00
return UrlBundle ::parse_url ( format! ( " http:// {} " , url ) ) ;
2023-04-05 21:54:27 +02:00
}
url
}
Err ( ParseError ::RelativeUrlWithoutBase ) = > {
2023-04-15 13:27:34 +02:00
let url_fmt = format! ( " http:// {} " , url ) ;
2023-06-20 02:59:18 +02:00
return UrlBundle ::parse_url ( url_fmt ) ;
2023-04-05 21:54:27 +02:00
}
Err ( _ ) = > panic! ( " Invalid URL " ) ,
} ;
2023-04-15 13:03:51 +02:00
// if the last character of the string is a slash, remove it.
let mut url_string = url . to_string ( ) ;
2023-04-25 17:41:14 +02:00
if url_string . ends_with ( '/' ) {
2023-04-15 13:03:51 +02:00
url_string . pop ( ) ;
}
2023-04-25 17:41:14 +02:00
url_string
2023-04-05 21:54:27 +02:00
}
2023-04-04 17:37:11 +02:00
}
#[ cfg(test) ]
2023-04-15 13:27:34 +02:00
mod lib {
2023-04-04 17:37:11 +02:00
use super ::* ;
#[ test ]
2023-04-05 21:54:27 +02:00
fn test_parse_url ( ) {
2023-06-20 02:59:18 +02:00
let mut result = UrlBundle ::parse_url ( String ::from ( " localhost:3000/ " ) ) ;
2023-04-05 21:54:27 +02:00
assert_eq! ( result , String ::from ( " http://localhost:3000 " ) ) ;
2023-06-20 02:59:18 +02:00
result = UrlBundle ::parse_url ( String ::from ( " https://some.url.com/ " ) ) ;
2023-04-15 13:27:34 +02:00
assert_eq! ( result , String ::from ( " https://some.url.com " ) ) ;
2023-06-20 02:59:18 +02:00
result = UrlBundle ::parse_url ( String ::from ( " https://some.url.com/ " ) ) ;
2023-04-15 13:27:34 +02:00
assert_eq! ( result , String ::from ( " https://some.url.com " ) ) ;
2023-06-20 02:59:18 +02:00
result = UrlBundle ::parse_url ( String ::from ( " https://some.url.com " ) ) ;
2023-04-15 13:27:34 +02:00
assert_eq! ( result , String ::from ( " https://some.url.com " ) ) ;
2023-04-04 17:37:11 +02:00
}
}