chorus/src/instance.rs

154 lines
4.9 KiB
Rust
Raw Normal View History

use std::cell::RefCell;
2023-07-28 17:33:23 +02:00
use std::collections::HashMap;
use std::fmt;
use std::rc::Rc;
use reqwest::Client;
2023-05-26 12:50:16 +02:00
use serde::{Deserialize, Serialize};
2023-07-28 17:33:23 +02:00
use crate::api::{Limit, LimitType};
use crate::errors::ChorusResult;
use crate::gateway::{Gateway, GatewayHandle};
use crate::ratelimiter::ChorusRequest;
use crate::types::types::subconfigs::limits::rates::RateLimits;
2023-05-25 23:09:18 +02:00
use crate::types::{GeneralConfiguration, User, UserSettings};
2023-06-20 02:59:18 +02:00
use crate::UrlBundle;
2023-04-16 22:16:22 +02:00
#[derive(Debug, Clone)]
2023-04-16 23:03:12 +02:00
/**
The [`Instance`] what you will be using to perform all sorts of actions on the Spacebar server.
2023-07-28 17:33:23 +02:00
If `limits_information` is `None`, then the instance will not be rate limited.
2023-04-16 23:03:12 +02:00
*/
pub struct Instance {
2023-06-20 02:59:18 +02:00
pub urls: UrlBundle,
2023-05-25 23:09:18 +02:00
pub instance_info: GeneralConfiguration,
2023-07-28 17:33:23 +02:00
pub limits_information: Option<LimitsInformation>,
pub client: Client,
2023-04-16 23:03:12 +02:00
}
2023-07-28 17:33:23 +02:00
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LimitsInformation {
pub ratelimits: HashMap<LimitType, Limit>,
pub configuration: RateLimits,
}
impl Instance {
/// Creates a new [`Instance`].
/// # Arguments
/// * `urls` - The [`URLBundle`] that contains all the URLs that are needed to connect to the Spacebar server.
/// * `requester` - The [`LimitedRequester`] that will be used to make requests to the Spacebar server.
/// # Errors
/// * [`InstanceError`] - If the instance cannot be created.
2023-07-28 17:33:23 +02:00
pub async fn new(urls: UrlBundle, limited: bool) -> ChorusResult<Instance> {
let limits_information;
if limited {
let limits_configuration =
Some(ChorusRequest::get_limits_config(&urls.api).await?.rate);
let limits = Some(ChorusRequest::limits_config_to_hashmap(
limits_configuration.as_ref().unwrap(),
));
limits_information = Some(LimitsInformation {
ratelimits: limits.unwrap(),
configuration: limits_configuration.unwrap(),
});
} else {
limits_information = None;
}
let mut instance = Instance {
2023-04-24 19:49:26 +02:00
urls: urls.clone(),
2023-06-19 10:27:32 +02:00
// Will be overwritten in the next step
instance_info: GeneralConfiguration::default(),
2023-07-28 17:33:23 +02:00
limits_information,
client: Client::new(),
};
2023-05-25 23:09:18 +02:00
instance.instance_info = match instance.general_configuration_schema().await {
Ok(schema) => schema,
2023-04-21 23:20:23 +02:00
Err(e) => {
2023-07-28 17:33:23 +02:00
log::warn!("Could not get instance configuration schema: {}", e);
GeneralConfiguration::default()
2023-04-21 23:20:23 +02:00
}
};
Ok(instance)
}
2023-07-28 17:33:23 +02:00
pub(crate) fn clone_limits_if_some(&self) -> Option<HashMap<LimitType, Limit>> {
if self.limits_information.is_some() {
return Some(self.limits_information.as_ref().unwrap().ratelimits.clone());
}
None
}
}
2023-05-26 12:50:16 +02:00
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
2023-04-21 23:20:23 +02:00
pub struct Token {
pub token: String,
}
2023-04-21 23:20:23 +02:00
impl fmt::Display for Token {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2023-04-21 23:20:23 +02:00
write!(f, "{}", self.token)
}
2023-04-16 22:16:22 +02:00
}
2023-04-17 21:31:15 +02:00
2023-05-25 23:09:18 +02:00
#[derive(Debug)]
pub struct UserMeta {
pub belongs_to: Rc<RefCell<Instance>>,
pub token: String,
2023-07-28 17:33:23 +02:00
pub limits: Option<HashMap<LimitType, Limit>>,
2023-05-25 23:09:18 +02:00
pub settings: UserSettings,
pub object: User,
2023-07-28 17:33:23 +02:00
pub gateway: GatewayHandle,
2023-05-25 23:09:18 +02:00
}
impl UserMeta {
pub fn token(&self) -> String {
self.token.clone()
}
pub fn set_token(&mut self, token: String) {
self.token = token;
}
pub fn new(
belongs_to: Rc<RefCell<Instance>>,
token: String,
2023-07-28 17:33:23 +02:00
limits: Option<HashMap<LimitType, Limit>>,
2023-05-25 23:09:18 +02:00
settings: UserSettings,
object: User,
2023-07-28 17:33:23 +02:00
gateway: GatewayHandle,
2023-05-25 23:09:18 +02:00
) -> UserMeta {
UserMeta {
belongs_to,
token,
limits,
settings,
object,
2023-07-28 17:33:23 +02:00
gateway,
}
}
/// Creates a new 'shell' of a user. The user does not exist as an object, and exists so that you have
/// a UserMeta object to make Rate Limited requests with. This is useful in scenarios like
/// registering or logging in to the Instance, where you do not yet have a User object, but still
/// need to make a RateLimited request. To use the [`GatewayHandle`], you will have to identify
/// first.
pub(crate) async fn shell(instance: Rc<RefCell<Instance>>, token: String) -> UserMeta {
let settings = UserSettings::default();
let object = User::default();
let wss_url = instance.borrow().urls.wss.clone();
// Dummy gateway object
let gateway = Gateway::new(wss_url).await.unwrap();
UserMeta {
token,
belongs_to: instance.clone(),
limits: instance
.borrow()
.limits_information
.as_ref()
.map(|info| info.ratelimits.clone()),
settings,
object,
gateway,
2023-05-25 23:09:18 +02:00
}
}
}