2023-06-11 13:52:31 +02:00
|
|
|
use std::cell::RefCell;
|
2023-07-09 18:38:02 +02:00
|
|
|
use std::collections::HashMap;
|
2023-06-11 13:52:31 +02:00
|
|
|
use std::fmt;
|
|
|
|
use std::rc::Rc;
|
|
|
|
|
2023-06-20 22:41:31 +02:00
|
|
|
use reqwest::Client;
|
2023-05-26 12:50:16 +02:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
2023-07-09 18:38:02 +02:00
|
|
|
use crate::api::{Limit, LimitType};
|
|
|
|
use crate::errors::ChorusResult;
|
|
|
|
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
|
|
|
|
2023-05-20 23:10:25 +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-09 18:38:02 +02:00
|
|
|
If `limits_information` is `None`, then the instance will not be rate limited.
|
2023-04-16 23:03:12 +02:00
|
|
|
*/
|
2023-05-07 12:39:04 +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-09 18:38:02 +02:00
|
|
|
pub limits_information: Option<LimitsInformation>,
|
2023-06-20 22:41:31 +02:00
|
|
|
pub client: Client,
|
2023-04-16 23:03:12 +02:00
|
|
|
}
|
|
|
|
|
2023-07-14 17:38:54 +02:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
2023-07-09 18:38:02 +02:00
|
|
|
pub struct LimitsInformation {
|
|
|
|
pub ratelimits: HashMap<LimitType, Limit>,
|
|
|
|
pub configuration: RateLimits,
|
|
|
|
}
|
|
|
|
|
2023-05-07 12:39:04 +02:00
|
|
|
impl Instance {
|
2023-04-19 20:41:33 +02:00
|
|
|
/// 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-09 18:38:02 +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;
|
|
|
|
}
|
2023-04-19 20:41:33 +02:00
|
|
|
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-09 18:38:02 +02:00
|
|
|
limits_information,
|
2023-06-20 22:41:31 +02:00
|
|
|
client: Client::new(),
|
2023-04-19 20:41:33 +02:00
|
|
|
};
|
2023-05-25 23:09:18 +02:00
|
|
|
instance.instance_info = match instance.general_configuration_schema().await {
|
2023-04-19 20:41:33 +02:00
|
|
|
Ok(schema) => schema,
|
2023-04-21 23:20:23 +02:00
|
|
|
Err(e) => {
|
2023-07-09 18:38:02 +02:00
|
|
|
log::warn!("Could not get instance configuration schema: {}", e);
|
|
|
|
GeneralConfiguration::default()
|
2023-04-21 23:20:23 +02:00
|
|
|
}
|
2023-04-19 20:41:33 +02:00
|
|
|
};
|
|
|
|
Ok(instance)
|
|
|
|
}
|
2023-07-09 18:38:02 +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-04-19 20:41:33 +02:00
|
|
|
}
|
|
|
|
|
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-19 20:41:33 +02:00
|
|
|
}
|
|
|
|
|
2023-04-21 23:20:23 +02:00
|
|
|
impl fmt::Display for Token {
|
2023-04-19 20:41:33 +02:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2023-04-21 23:20:23 +02:00
|
|
|
write!(f, "{}", self.token)
|
2023-04-19 20:41:33 +02:00
|
|
|
}
|
2023-04-16 22:16:22 +02:00
|
|
|
}
|
2023-04-17 21:31:15 +02:00
|
|
|
|
Join/Leave Guilds, (Group) DMs and minor improvements (#157)
## Summary:
**Added:**
- Schemas `PrivateChannelCreateSchema` `ChannelInviteCreateSchema`, `AddChannelRecipientSchema` recursively (including schemas which were needed to create these schemas)
- Methods `create_private_channel`, `leave_guild`, `accept_invite`, `create_user_invite`, `create_guild_invite`, `add_channel_recipient`, `remove_channel_recipient`
- Integration tests for the functionality covered by implementing #45
- Documentation in some places where I noticed it would be useful to have some
- `create_user` method in `/src/tests`: Cuts down on test boilerplate needed to create an addition test user
**Changed:**
- `.gitignore`
- Added `.DS_store` files to gitignore (some weird macos files), removed Cargo.lock, as Cargo.lock should be included for libraries
- Added a lot of default trait derives like Clone, Copy, PartialEq, Eq, Ord, PartialOrd to structs and enums where I saw them missing
- Added missing `teardown()` calls to the integration tests
- Renamed integration test files in `/src/tests` dir to all be plural: `channel.rs` -> `channels.rs`
- Made more fields on `User` type `Option<>`
- All instances in `/src/tests` where a second test user was created using a RegistrationSchema and the register_user method were replaced with the new `create_user` method
- README.md: Marked roadmap fields covered by #45 as implemented
- Changed visibility of `/src/tests/common/mod.rs` methods from `pub` to `pub(crate)`. In hindsight, this was probably not required, haha
**Removed:**
- Unneeded import in`src/types/config/types/guild_configuration.rs`
## Commit log:
* Add .DS_store, remove Cargo.lock
* Create PrivateChannelCreateSchema
* pub use users
* add channels.rs
* create channels.rs
* Add Deserialize/Serialize derives
* Implement create_private_channel
* Add create_dm() test
* Make optional fields on `User` `Option<>`
* Check boxes for implemented features
* Create users/guilds.rs
* Remove unneeded import
* Add UserMeta::leave_guild()
* Create api/invites/mod.rs
* Add debug print to send_request
* Rename tests files
* Create invites.rs
* create invite.rs
* Add documentation
* Implement accept_invite
* Sort fields on Channel alphabetically
* Add invite mod
* Add forgotten teardown() at test end
* change visiblities, add create_user()
* Implement `create_user_invite()`
* start working on invite tests
* Add allow flags
* Fix bad url
* Create CreateChannelInviteSchema and friends
* remove non-implemented test code
* add body to requests
* Add Clone to UserMeta
* More comprehensive error message when running into a deserialization error
* Add arguments documentation to accept_invite
* Add Eq derive to GuildFeaturesList
* Add Eq derive to Emoji
* Add Eq derive to GuildBan
* Add create_accept_invite() test
* Add Default derive to ChannelCreateSchema
* Change create_guild_invite to return GuildInvite
* Dates as chrono::Date(Utc); sort alphabetically
* Add default derives wherever possible
* Implement add_- and remove_channel_recipient
* Create AddChannelRecipientSchema
* replace otheruser regs with bundle.creeate_user()
* Add (disabled) test remove_add_person_from_to_dm()
2023-07-17 19:36:28 +02:00
|
|
|
#[derive(Debug, Clone)]
|
2023-05-25 23:09:18 +02:00
|
|
|
pub struct UserMeta {
|
|
|
|
pub belongs_to: Rc<RefCell<Instance>>,
|
|
|
|
pub token: String,
|
2023-07-09 18:38:02 +02:00
|
|
|
pub limits: Option<HashMap<LimitType, Limit>>,
|
2023-05-25 23:09:18 +02:00
|
|
|
pub settings: UserSettings,
|
2023-06-10 00:35:51 +02:00
|
|
|
pub object: User,
|
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-09 18:38:02 +02:00
|
|
|
limits: Option<HashMap<LimitType, Limit>>,
|
2023-05-25 23:09:18 +02:00
|
|
|
settings: UserSettings,
|
2023-06-10 00:35:51 +02:00
|
|
|
object: User,
|
2023-05-25 23:09:18 +02:00
|
|
|
) -> UserMeta {
|
|
|
|
UserMeta {
|
|
|
|
belongs_to,
|
|
|
|
token,
|
|
|
|
limits,
|
|
|
|
settings,
|
|
|
|
object,
|
|
|
|
}
|
|
|
|
}
|
2023-07-09 18:38:02 +02:00
|
|
|
|
|
|
|
/// 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.
|
|
|
|
pub(crate) fn shell(instance: Rc<RefCell<Instance>>, token: String) -> UserMeta {
|
|
|
|
let settings = UserSettings::default();
|
|
|
|
let object = User::default();
|
|
|
|
UserMeta {
|
|
|
|
belongs_to: instance.clone(),
|
|
|
|
token,
|
|
|
|
limits: instance
|
|
|
|
.borrow()
|
|
|
|
.limits_information
|
|
|
|
.as_ref()
|
|
|
|
.map(|info| info.ratelimits.clone()),
|
|
|
|
settings,
|
|
|
|
object,
|
|
|
|
}
|
|
|
|
}
|
2023-05-25 23:09:18 +02:00
|
|
|
}
|