chorus/src/lib.rs

117 lines
4.1 KiB
Rust
Raw Normal View History

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
)]
#[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
#[cfg(not(target_arch = "wasm32"))]
pub type Gateway = DefaultGateway;
#[cfg(not(target_arch = "wasm32"))]
pub type GatewayHandle = DefaultGatewayHandle;
use gateway::DefaultGateway;
use gateway::DefaultGatewayHandle;
use url::{ParseError, Url};
#[cfg(feature = "client")]
pub mod api;
pub mod errors;
#[cfg(feature = "client")]
pub mod gateway;
#[cfg(feature = "client")]
pub mod instance;
#[cfg(feature = "client")]
Ratelimiter overhaul (#144) * Rename limits and limit to have better names * Remove empty lines * Remove handle_request (moved to requestlimiter) * Start working on new ratelimiter * Make limits Option, add "limited?" to constructor * Add missing logic to send_request * Rename Limits * Create Ratelimits and Limit Struct * Define Limit * Import Ratelimits * Define get_rate_limits * Remove unused import * + check_rate_limits & limits_config_to_ratelimits * Remove Absolute Limits These limits are not meant to be tracked anyways. * add ratelimits is_exhausted * Add error handling and send request checking * change limits to option ratelimits * Add strum * Change Ratelimits to Hashmap * Remove ratelimits in favor of hashmap * Change code from struct to hashmap * start working on update rate limits * Remove wrong import * Rename ChorusLibError to ChorusError * Documented the chorus errors * Made error documentation docstring * Make ReceivedErrorCodeError have error string * Remove unneeded import * Match changes in errors.rs * Improve update_rate_limits and can_send_request * add ratelimits.to_hash_map() * use instances' client instead of new client * add LimitsConfiguration to instance * improve update_limits, change a method name * Fix un-updated errors * Get LimitConfiguration in a sane way * Move common.rs into ratelimiter::ChorusRequest * Delete common.rs * Make instance.rs use overhauled errors * Refactor to use new Rate limiting implementation * Refactor to use new Rate limiting implementation * Refactor to use new Rate limiting implementation * Refactor to use new Rate limiting implementation * Refactor to use new Rate limiting implementation * Refactor to use new Rate limiting implementation * update ratelimiter implementation across all files * Fix remaining errors post-refactor * Changed Enum case to be correct * Use result * Re-add missing body to request * Remove unneeded late initalization * Change visibility from pub to pub(crate) I feel like these core methods don't need to be exposed as public API. * Remove unnecessary import * Fix clippy warnings * Add docstring * Change Error names across all files * Update Cargo.toml Strum is not needed * Update ratelimits.rs * Update ratelimits.rs * Bug/discord instance info unavailable (#146) * Change text to be more ambigous * Use default Configuration instead of erroring out * Emit warning log if instance config cant be gotten * Remove import * Update src/instance.rs Co-authored-by: SpecificProtagonist <specificprotagonist@posteo.org> * Add missing closing bracket * Put limits and limits_configuration as one struct * Derive Hash * remove import * rename limits and limits_configuration * Save clone call * Change LimitsConfiguration to RateLimits `LimitsConfiguration` is in no way related to whether the instance has API rate limits enabled or not. Therefore, it has been replaced with what it should have been all along. * Add ensure_limit_in_map(), add `window` to `Limit` * Remove unneeded var * Remove import * Clean up unneeded things Dead code warnings have been supressed, but flagged as FIXME so they don't get forgotten. Anyone using tools like TODO Tree in VSCode can still see that they are there, however, they will not be shown as warnings anymore * Remove nested submodule `limit` * Add doc comments * Add more doc comments * Add some log messages to some methods --------- Co-authored-by: SpecificProtagonist <specificprotagonist@posteo.org>
2023-07-09 18:38:02 +02:00
pub mod ratelimiter;
2023-05-25 21:11:08 +02:00
pub mod types;
#[cfg(feature = "client")]
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:
/// ```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) => {
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"),
};
// 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('/') {
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)]
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/"));
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/"));
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"));
assert_eq!(result, String::from("https://some.url.com"));
2023-04-04 17:37:11 +02:00
}
}