merge with dev
This commit is contained in:
commit
93d32944b1
|
@ -36,7 +36,7 @@ impl Message {
|
||||||
chorus_request.deserialize_response::<Message>(user).await
|
chorus_request.deserialize_response::<Message>(user).await
|
||||||
} else {
|
} else {
|
||||||
for (index, attachment) in message.attachments.iter_mut().enumerate() {
|
for (index, attachment) in message.attachments.iter_mut().enumerate() {
|
||||||
attachment.get_mut(index).unwrap().set_id(index as i16);
|
attachment.get_mut(index).unwrap().id = Some(index as i16);
|
||||||
}
|
}
|
||||||
let mut form = reqwest::multipart::Form::new();
|
let mut form = reqwest::multipart::Form::new();
|
||||||
let payload_json = to_string(&message).unwrap();
|
let payload_json = to_string(&message).unwrap();
|
||||||
|
@ -45,8 +45,8 @@ impl Message {
|
||||||
form = form.part("payload_json", payload_field);
|
form = form.part("payload_json", payload_field);
|
||||||
|
|
||||||
for (index, attachment) in message.attachments.unwrap().into_iter().enumerate() {
|
for (index, attachment) in message.attachments.unwrap().into_iter().enumerate() {
|
||||||
let (attachment_content, current_attachment) = attachment.move_content();
|
let attachment_content = attachment.content;
|
||||||
let (attachment_filename, _) = current_attachment.move_filename();
|
let attachment_filename = attachment.filename;
|
||||||
let part_name = format!("files[{}]", index);
|
let part_name = format!("files[{}]", index);
|
||||||
let content_disposition = format!(
|
let content_disposition = format!(
|
||||||
"form-data; name=\"{}\"'; filename=\"{}\"",
|
"form-data; name=\"{}\"'; filename=\"{}\"",
|
||||||
|
|
|
@ -40,10 +40,19 @@ impl GatewayHandle {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Recursively observes a [`Shared`] object, by making sure all [`Composite `] fields within
|
||||||
|
/// that object and its children are being watched.
|
||||||
|
///
|
||||||
|
/// Observing means, that if new information arrives about the observed object or its children,
|
||||||
|
/// the object automatically gets updated, without you needing to request new information about
|
||||||
|
/// the object in question from the API, which is expensive and can lead to rate limiting.
|
||||||
|
///
|
||||||
|
/// The [`Shared`] object returned by this method points to a different object than the one
|
||||||
|
/// being supplied as a &self function argument.
|
||||||
pub async fn observe<T: Updateable + Clone + Debug + Composite<T>>(
|
pub async fn observe<T: Updateable + Clone + Debug + Composite<T>>(
|
||||||
&self,
|
&self,
|
||||||
object: Arc<RwLock<T>>,
|
object: Shared<T>,
|
||||||
) -> Arc<RwLock<T>> {
|
) -> Shared<T> {
|
||||||
let mut store = self.store.lock().await;
|
let mut store = self.store.lock().await;
|
||||||
let id = object.read().unwrap().id();
|
let id = object.read().unwrap().id();
|
||||||
if let Some(channel) = store.get(&id) {
|
if let Some(channel) = store.get(&id) {
|
||||||
|
@ -84,7 +93,7 @@ impl GatewayHandle {
|
||||||
/// with all of its observable fields being observed.
|
/// with all of its observable fields being observed.
|
||||||
pub async fn observe_and_into_inner<T: Updateable + Clone + Debug + Composite<T>>(
|
pub async fn observe_and_into_inner<T: Updateable + Clone + Debug + Composite<T>>(
|
||||||
&self,
|
&self,
|
||||||
object: Arc<RwLock<T>>,
|
object: Shared<T>,
|
||||||
) -> T {
|
) -> T {
|
||||||
let channel = self.observe(object.clone()).await;
|
let channel = self.observe(object.clone()).await;
|
||||||
let object = channel.read().unwrap().clone();
|
let object = channel.read().unwrap().clone();
|
||||||
|
|
|
@ -128,3 +128,11 @@ impl<T: WebSocketEvent> GatewayEvent<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A type alias for [`Arc<RwLock<T>>`], used to make the public facing API concerned with
|
||||||
|
/// Composite structs more ergonomic.
|
||||||
|
/// ## Note
|
||||||
|
///
|
||||||
|
/// While `T` does not have to implement `Composite` to be used with `Shared`,
|
||||||
|
/// the primary use of `Shared` is with types that implement `Composite`.
|
||||||
|
pub type Shared<T> = Arc<RwLock<T>>;
|
||||||
|
|
|
@ -9,7 +9,7 @@ use reqwest::Client;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::errors::ChorusResult;
|
use crate::errors::ChorusResult;
|
||||||
use crate::gateway::{Gateway, GatewayHandle};
|
use crate::gateway::{Gateway, GatewayHandle, Shared};
|
||||||
use crate::ratelimiter::ChorusRequest;
|
use crate::ratelimiter::ChorusRequest;
|
||||||
use crate::types::types::subconfigs::limits::rates::RateLimits;
|
use crate::types::types::subconfigs::limits::rates::RateLimits;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
|
@ -19,6 +19,7 @@ use crate::UrlBundle;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||||
/// The [`Instance`]; what you will be using to perform all sorts of actions on the Spacebar server.
|
/// The [`Instance`]; what you will be using to perform all sorts of actions on the Spacebar server.
|
||||||
|
///
|
||||||
/// If `limits_information` is `None`, then the instance will not be rate limited.
|
/// If `limits_information` is `None`, then the instance will not be rate limited.
|
||||||
pub struct Instance {
|
pub struct Instance {
|
||||||
pub urls: UrlBundle,
|
pub urls: UrlBundle,
|
||||||
|
@ -36,8 +37,6 @@ impl PartialEq for Instance {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for Instance {}
|
|
||||||
|
|
||||||
impl std::hash::Hash for Instance {
|
impl std::hash::Hash for Instance {
|
||||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
self.urls.hash(state);
|
self.urls.hash(state);
|
||||||
|
@ -72,8 +71,17 @@ impl PartialEq for LimitsInformation {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instance {
|
impl Instance {
|
||||||
/// Creates a new [`Instance`] from the [relevant instance urls](UrlBundle). To create an Instance from one singular url, use [`Instance::from_root_url()`].
|
pub(crate) fn clone_limits_if_some(&self) -> Option<HashMap<LimitType, Limit>> {
|
||||||
async fn from_url_bundle(urls: UrlBundle) -> ChorusResult<Instance> {
|
if self.limits_information.is_some() {
|
||||||
|
return Some(self.limits_information.as_ref().unwrap().ratelimits.clone());
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new [`Instance`] from the [relevant instance urls](UrlBundle).
|
||||||
|
///
|
||||||
|
/// To create an Instance from one singular url, use [`Instance::new()`].
|
||||||
|
pub async fn from_url_bundle(urls: UrlBundle) -> ChorusResult<Instance> {
|
||||||
let is_limited: Option<LimitsConfiguration> = Instance::is_limited(&urls.api).await?;
|
let is_limited: Option<LimitsConfiguration> = Instance::is_limited(&urls.api).await?;
|
||||||
let limit_information;
|
let limit_information;
|
||||||
|
|
||||||
|
@ -103,17 +111,9 @@ impl Instance {
|
||||||
Ok(instance)
|
Ok(instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new [`Instance`] by trying to get the [relevant instance urls](UrlBundle) from a root url.
|
/// Creates a new [`Instance`] by trying to get the [relevant instance urls](UrlBundle) from a root url.
|
||||||
/// Shorthand for `Instance::new(UrlBundle::from_root_domain(root_domain).await?)`.
|
|
||||||
///
|
///
|
||||||
/// If `limited` is `true`, then Chorus will track and enforce rate limits for this instance.
|
/// Shorthand for `Instance::from_url_bundle(UrlBundle::from_root_domain(root_domain).await?)`.
|
||||||
pub async fn new(root_url: &str) -> ChorusResult<Instance> {
|
pub async fn new(root_url: &str) -> ChorusResult<Instance> {
|
||||||
let urls = UrlBundle::from_root_url(root_url).await?;
|
let urls = UrlBundle::from_root_url(root_url).await?;
|
||||||
Instance::from_url_bundle(urls).await
|
Instance::from_url_bundle(urls).await
|
||||||
|
@ -153,11 +153,11 @@ impl fmt::Display for Token {
|
||||||
/// It is used for most authenticated actions on a Spacebar server.
|
/// It is used for most authenticated actions on a Spacebar server.
|
||||||
/// It also has its own [Gateway] connection.
|
/// It also has its own [Gateway] connection.
|
||||||
pub struct ChorusUser {
|
pub struct ChorusUser {
|
||||||
pub belongs_to: Arc<RwLock<Instance>>,
|
pub belongs_to: Shared<Instance>,
|
||||||
pub token: String,
|
pub token: String,
|
||||||
pub limits: Option<HashMap<LimitType, Limit>>,
|
pub limits: Option<HashMap<LimitType, Limit>>,
|
||||||
pub settings: Arc<RwLock<UserSettings>>,
|
pub settings: Shared<UserSettings>,
|
||||||
pub object: Arc<RwLock<User>>,
|
pub object: Shared<User>,
|
||||||
pub gateway: GatewayHandle,
|
pub gateway: GatewayHandle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,8 +169,6 @@ impl PartialEq for ChorusUser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for ChorusUser {}
|
|
||||||
|
|
||||||
impl ChorusUser {
|
impl ChorusUser {
|
||||||
pub fn token(&self) -> String {
|
pub fn token(&self) -> String {
|
||||||
self.token.clone()
|
self.token.clone()
|
||||||
|
@ -186,11 +184,11 @@ impl ChorusUser {
|
||||||
/// This isn't the prefered way to create a ChorusUser.
|
/// This isn't the prefered way to create a ChorusUser.
|
||||||
/// See [Instance::login_account] and [Instance::register_account] instead.
|
/// See [Instance::login_account] and [Instance::register_account] instead.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
belongs_to: Arc<RwLock<Instance>>,
|
belongs_to: Shared<Instance>,
|
||||||
token: String,
|
token: String,
|
||||||
limits: Option<HashMap<LimitType, Limit>>,
|
limits: Option<HashMap<LimitType, Limit>>,
|
||||||
settings: Arc<RwLock<UserSettings>>,
|
settings: Shared<UserSettings>,
|
||||||
object: Arc<RwLock<User>>,
|
object: Shared<User>,
|
||||||
gateway: GatewayHandle,
|
gateway: GatewayHandle,
|
||||||
) -> ChorusUser {
|
) -> ChorusUser {
|
||||||
ChorusUser {
|
ChorusUser {
|
||||||
|
@ -208,7 +206,7 @@ impl ChorusUser {
|
||||||
/// registering or logging in to the Instance, where you do not yet have a User object, but still
|
/// 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
|
/// need to make a RateLimited request. To use the [`GatewayHandle`], you will have to identify
|
||||||
/// first.
|
/// first.
|
||||||
pub(crate) async fn shell(instance: Arc<RwLock<Instance>>, token: String) -> ChorusUser {
|
pub(crate) async fn shell(instance: Shared<Instance>, token: String) -> ChorusUser {
|
||||||
let settings = Arc::new(RwLock::new(UserSettings::default()));
|
let settings = Arc::new(RwLock::new(UserSettings::default()));
|
||||||
let object = Arc::new(RwLock::new(User::default()));
|
let object = Arc::new(RwLock::new(User::default()));
|
||||||
let wss_url = instance.read().unwrap().urls.wss.clone();
|
let wss_url = instance.read().unwrap().urls.wss.clone();
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
use crate::types::utils::Snowflake;
|
use crate::types::utils::Snowflake;
|
||||||
use crate::types::{Team, User};
|
use crate::types::{Team, User};
|
||||||
|
|
||||||
|
@ -27,7 +26,7 @@ pub struct Application {
|
||||||
pub bot_require_code_grant: bool,
|
pub bot_require_code_grant: bool,
|
||||||
pub verify_key: String,
|
pub verify_key: String,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub owner: Arc<RwLock<User>>,
|
pub owner: Shared<User>,
|
||||||
pub flags: u64,
|
pub flags: u64,
|
||||||
#[cfg(feature = "sqlx")]
|
#[cfg(feature = "sqlx")]
|
||||||
pub redirect_uris: Option<sqlx::types::Json<Vec<String>>>,
|
pub redirect_uris: Option<sqlx::types::Json<Vec<String>>>,
|
||||||
|
@ -49,7 +48,7 @@ pub struct Application {
|
||||||
#[cfg(feature = "sqlx")]
|
#[cfg(feature = "sqlx")]
|
||||||
pub install_params: Option<sqlx::types::Json<InstallParams>>,
|
pub install_params: Option<sqlx::types::Json<InstallParams>>,
|
||||||
#[cfg(not(feature = "sqlx"))]
|
#[cfg(not(feature = "sqlx"))]
|
||||||
pub install_params: Option<Arc<RwLock<InstallParams>>>,
|
pub install_params: Option<Shared<InstallParams>>,
|
||||||
pub terms_of_service_url: Option<String>,
|
pub terms_of_service_url: Option<String>,
|
||||||
pub privacy_policy_url: Option<String>,
|
pub privacy_policy_url: Option<String>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
|
@ -142,7 +141,7 @@ pub struct ApplicationCommand {
|
||||||
pub application_id: Snowflake,
|
pub application_id: Snowflake,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub description: String,
|
pub description: String,
|
||||||
pub options: Vec<Arc<RwLock<ApplicationCommandOption>>>,
|
pub options: Vec<Shared<ApplicationCommandOption>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
@ -154,7 +153,7 @@ pub struct ApplicationCommandOption {
|
||||||
pub description: String,
|
pub description: String,
|
||||||
pub required: bool,
|
pub required: bool,
|
||||||
pub choices: Vec<ApplicationCommandOptionChoice>,
|
pub choices: Vec<ApplicationCommandOptionChoice>,
|
||||||
pub options: Arc<RwLock<Vec<ApplicationCommandOption>>>,
|
pub options: Shared<Vec<ApplicationCommandOption>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
@ -190,14 +189,14 @@ pub enum ApplicationCommandOptionType {
|
||||||
pub struct ApplicationCommandInteractionData {
|
pub struct ApplicationCommandInteractionData {
|
||||||
pub id: Snowflake,
|
pub id: Snowflake,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub options: Vec<Arc<RwLock<ApplicationCommandInteractionDataOption>>>,
|
pub options: Vec<Shared<ApplicationCommandInteractionDataOption>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct ApplicationCommandInteractionDataOption {
|
pub struct ApplicationCommandInteractionDataOption {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub value: Value,
|
pub value: Value,
|
||||||
pub options: Vec<Arc<RwLock<ApplicationCommandInteractionDataOption>>>,
|
pub options: Vec<Shared<ApplicationCommandInteractionDataOption>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
|
@ -206,7 +205,7 @@ pub struct GuildApplicationCommandPermissions {
|
||||||
pub id: Snowflake,
|
pub id: Snowflake,
|
||||||
pub application_id: Snowflake,
|
pub application_id: Snowflake,
|
||||||
pub guild_id: Snowflake,
|
pub guild_id: Snowflake,
|
||||||
pub permissions: Vec<Arc<RwLock<ApplicationCommandPermission>>>,
|
pub permissions: Vec<Shared<ApplicationCommandPermission>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
|
|
@ -55,73 +55,3 @@ pub struct PartialDiscordFileAttachment {
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
pub content: Vec<u8>,
|
pub content: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialDiscordFileAttachment {
|
|
||||||
/// Moves `self.content` out of `self` and returns it.
|
|
||||||
pub fn move_content(self) -> (Vec<u8>, PartialDiscordFileAttachment) {
|
|
||||||
let content = self.content;
|
|
||||||
let updated_struct = PartialDiscordFileAttachment {
|
|
||||||
id: self.id,
|
|
||||||
filename: self.filename,
|
|
||||||
description: self.description,
|
|
||||||
content_type: self.content_type,
|
|
||||||
size: self.size,
|
|
||||||
url: self.url,
|
|
||||||
proxy_url: self.proxy_url,
|
|
||||||
height: self.height,
|
|
||||||
width: self.width,
|
|
||||||
ephemeral: self.ephemeral,
|
|
||||||
duration_secs: self.duration_secs,
|
|
||||||
waveform: self.waveform,
|
|
||||||
content: Vec::new(),
|
|
||||||
};
|
|
||||||
(content, updated_struct)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Moves `self.filename` out of `self` and returns it.
|
|
||||||
pub fn move_filename(self) -> (String, PartialDiscordFileAttachment) {
|
|
||||||
let filename = self.filename;
|
|
||||||
let updated_struct = PartialDiscordFileAttachment {
|
|
||||||
id: self.id,
|
|
||||||
filename: String::new(),
|
|
||||||
description: self.description,
|
|
||||||
content_type: self.content_type,
|
|
||||||
size: self.size,
|
|
||||||
url: self.url,
|
|
||||||
proxy_url: self.proxy_url,
|
|
||||||
height: self.height,
|
|
||||||
width: self.width,
|
|
||||||
|
|
||||||
ephemeral: self.ephemeral,
|
|
||||||
duration_secs: self.duration_secs,
|
|
||||||
waveform: self.waveform,
|
|
||||||
content: self.content,
|
|
||||||
};
|
|
||||||
(filename, updated_struct)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Moves `self.content_type` out of `self` and returns it.
|
|
||||||
pub fn move_content_type(self) -> (Option<String>, PartialDiscordFileAttachment) {
|
|
||||||
let content_type = self.content_type;
|
|
||||||
let updated_struct = PartialDiscordFileAttachment {
|
|
||||||
id: self.id,
|
|
||||||
filename: self.filename,
|
|
||||||
description: self.description,
|
|
||||||
content_type: None,
|
|
||||||
size: self.size,
|
|
||||||
url: self.url,
|
|
||||||
proxy_url: self.proxy_url,
|
|
||||||
height: self.height,
|
|
||||||
width: self.width,
|
|
||||||
ephemeral: self.ephemeral,
|
|
||||||
duration_secs: self.duration_secs,
|
|
||||||
waveform: self.waveform,
|
|
||||||
content: self.content,
|
|
||||||
};
|
|
||||||
(content_type, updated_struct)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_id(&mut self, id: i16) {
|
|
||||||
self.id = Some(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
use crate::types::utils::Snowflake;
|
use crate::types::utils::Snowflake;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
/// See <https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object>
|
/// See <https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object>
|
||||||
pub struct AuditLogEntry {
|
pub struct AuditLogEntry {
|
||||||
pub target_id: Option<String>,
|
pub target_id: Option<String>,
|
||||||
pub changes: Option<Vec<Arc<RwLock<AuditLogChange>>>>,
|
pub changes: Option<Vec<Shared<AuditLogChange>>>,
|
||||||
pub user_id: Option<Snowflake>,
|
pub user_id: Option<Snowflake>,
|
||||||
pub id: Snowflake,
|
pub id: Snowflake,
|
||||||
// to:do implement an enum for these types
|
// to:do implement an enum for these types
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use std::sync::{Arc, RwLock};
|
use crate::gateway::Shared;
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use crate::gateway::Updateable;
|
use crate::gateway::Updateable;
|
||||||
|
|
||||||
|
@ -21,8 +20,8 @@ pub struct AutoModerationRule {
|
||||||
pub creator_id: Snowflake,
|
pub creator_id: Snowflake,
|
||||||
pub event_type: AutoModerationRuleEventType,
|
pub event_type: AutoModerationRuleEventType,
|
||||||
pub trigger_type: AutoModerationRuleTriggerType,
|
pub trigger_type: AutoModerationRuleTriggerType,
|
||||||
pub trigger_metadata: Arc<RwLock<AutoModerationRuleTriggerMetadata>>,
|
pub trigger_metadata: Shared<AutoModerationRuleTriggerMetadata>,
|
||||||
pub actions: Vec<Arc<RwLock<AutoModerationAction>>>,
|
pub actions: Vec<Shared<AutoModerationAction>>,
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
pub exempt_roles: Vec<Snowflake>,
|
pub exempt_roles: Vec<Snowflake>,
|
||||||
pub exempt_channels: Vec<Snowflake>,
|
pub exempt_channels: Vec<Snowflake>,
|
||||||
|
@ -99,7 +98,7 @@ pub enum AutoModerationRuleKeywordPresetType {
|
||||||
pub struct AutoModerationAction {
|
pub struct AutoModerationAction {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub action_type: AutoModerationActionType,
|
pub action_type: AutoModerationActionType,
|
||||||
pub metadata: Option<Arc<RwLock<AutoModerationActionMetadata>>>,
|
pub metadata: Option<Shared<AutoModerationActionMetadata>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)]
|
#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Default)]
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_aux::prelude::deserialize_string_from_number;
|
use serde_aux::prelude::deserialize_string_from_number;
|
||||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
entities::{GuildMember, User},
|
entities::{GuildMember, User},
|
||||||
utils::Snowflake,
|
utils::Snowflake,
|
||||||
|
@ -71,13 +70,13 @@ pub struct Channel {
|
||||||
pub permission_overwrites: Option<sqlx::types::Json<Vec<PermissionOverwrite>>>,
|
pub permission_overwrites: Option<sqlx::types::Json<Vec<PermissionOverwrite>>>,
|
||||||
#[cfg(not(feature = "sqlx"))]
|
#[cfg(not(feature = "sqlx"))]
|
||||||
#[cfg_attr(feature = "client", observe_option_vec)]
|
#[cfg_attr(feature = "client", observe_option_vec)]
|
||||||
pub permission_overwrites: Option<Vec<Arc<RwLock<PermissionOverwrite>>>>,
|
pub permission_overwrites: Option<Vec<Shared<PermissionOverwrite>>>,
|
||||||
pub permissions: Option<String>,
|
pub permissions: Option<String>,
|
||||||
pub position: Option<i32>,
|
pub position: Option<i32>,
|
||||||
pub rate_limit_per_user: Option<i32>,
|
pub rate_limit_per_user: Option<i32>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
#[cfg_attr(feature = "client", observe_option_vec)]
|
#[cfg_attr(feature = "client", observe_option_vec)]
|
||||||
pub recipients: Option<Vec<Arc<RwLock<User>>>>,
|
pub recipients: Option<Vec<Shared<User>>>,
|
||||||
pub rtc_region: Option<String>,
|
pub rtc_region: Option<String>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub thread_metadata: Option<ThreadMetadata>,
|
pub thread_metadata: Option<ThreadMetadata>,
|
||||||
|
@ -171,7 +170,7 @@ pub struct ThreadMember {
|
||||||
pub user_id: Option<Snowflake>,
|
pub user_id: Option<Snowflake>,
|
||||||
pub join_timestamp: Option<String>,
|
pub join_timestamp: Option<String>,
|
||||||
pub flags: Option<u64>,
|
pub flags: Option<u64>,
|
||||||
pub member: Option<Arc<RwLock<GuildMember>>>,
|
pub member: Option<Shared<GuildMember>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||||
|
|
|
@ -15,20 +15,29 @@ impl ConfigEntity {
|
||||||
let Some(v) = self.value.as_ref() else {
|
let Some(v) = self.value.as_ref() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
Some(v.as_str().expect("value is not a string").to_string())
|
let Some(v) = v.as_str() else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
Some(v.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_bool(&self) -> Option<bool> {
|
pub fn as_bool(&self) -> Option<bool> {
|
||||||
let Some(v) = self.value.as_ref() else {
|
let Some(v) = self.value.as_ref() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
Some(v.as_bool().expect("value is not a boolean"))
|
let Some(v) = v.as_bool() else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
Some(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_int(&self) -> Option<i64> {
|
pub fn as_int(&self) -> Option<i64> {
|
||||||
let Some(v) = self.value.as_ref() else {
|
let Some(v) = self.value.as_ref() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
Some(v.as_i64().expect("value is not a number"))
|
let Some(v) = v.as_i64() else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
Some(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
use crate::types::entities::User;
|
use crate::types::entities::User;
|
||||||
use crate::types::Snowflake;
|
use crate::types::Snowflake;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ pub struct Emoji {
|
||||||
#[cfg(not(feature = "sqlx"))]
|
#[cfg(not(feature = "sqlx"))]
|
||||||
pub roles: Option<Vec<Snowflake>>,
|
pub roles: Option<Vec<Snowflake>>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub user: Option<Arc<RwLock<User>>>,
|
pub user: Option<Shared<User>>,
|
||||||
pub require_colons: Option<bool>,
|
pub require_colons: Option<bool>,
|
||||||
pub managed: Option<bool>,
|
pub managed: Option<bool>,
|
||||||
pub animated: Option<bool>,
|
pub animated: Option<bool>,
|
||||||
|
@ -62,37 +62,3 @@ impl PartialEq for Emoji {
|
||||||
|| self.available != other.available)
|
|| self.available != other.available)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd for Emoji {
|
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
|
||||||
match self.id.partial_cmp(&other.id) {
|
|
||||||
Some(core::cmp::Ordering::Equal) => {}
|
|
||||||
ord => return ord,
|
|
||||||
}
|
|
||||||
match self.name.partial_cmp(&other.name) {
|
|
||||||
Some(core::cmp::Ordering::Equal) => {}
|
|
||||||
ord => return ord,
|
|
||||||
}
|
|
||||||
match self.roles.partial_cmp(&other.roles) {
|
|
||||||
Some(core::cmp::Ordering::Equal) => {}
|
|
||||||
ord => return ord,
|
|
||||||
}
|
|
||||||
match self.roles.partial_cmp(&other.roles) {
|
|
||||||
Some(core::cmp::Ordering::Equal) => {}
|
|
||||||
ord => return ord,
|
|
||||||
}
|
|
||||||
match self.require_colons.partial_cmp(&other.require_colons) {
|
|
||||||
Some(core::cmp::Ordering::Equal) => {}
|
|
||||||
ord => return ord,
|
|
||||||
}
|
|
||||||
match self.managed.partial_cmp(&other.managed) {
|
|
||||||
Some(core::cmp::Ordering::Equal) => {}
|
|
||||||
ord => return ord,
|
|
||||||
}
|
|
||||||
match self.animated.partial_cmp(&other.animated) {
|
|
||||||
Some(core::cmp::Ordering::Equal) => {}
|
|
||||||
ord => return ord,
|
|
||||||
}
|
|
||||||
self.available.partial_cmp(&other.available)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
use crate::types::types::guild_configuration::GuildFeaturesList;
|
use crate::types::types::guild_configuration::GuildFeaturesList;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
entities::{Channel, Emoji, RoleObject, Sticker, User, VoiceState, Webhook},
|
entities::{Channel, Emoji, RoleObject, Sticker, User, VoiceState, Webhook},
|
||||||
|
@ -45,14 +45,14 @@ pub struct Guild {
|
||||||
pub bans: Option<Vec<GuildBan>>,
|
pub bans: Option<Vec<GuildBan>>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
#[cfg_attr(feature = "client", observe_option_vec)]
|
#[cfg_attr(feature = "client", observe_option_vec)]
|
||||||
pub channels: Option<Vec<Arc<RwLock<Channel>>>>,
|
pub channels: Option<Vec<Shared<Channel>>>,
|
||||||
pub default_message_notifications: Option<MessageNotificationLevel>,
|
pub default_message_notifications: Option<MessageNotificationLevel>,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub discovery_splash: Option<String>,
|
pub discovery_splash: Option<String>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
#[cfg_attr(feature = "client", observe_vec)]
|
#[cfg_attr(feature = "client", observe_vec)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub emojis: Vec<Arc<RwLock<Emoji>>>,
|
pub emojis: Vec<Shared<Emoji>>,
|
||||||
pub explicit_content_filter: Option<i32>,
|
pub explicit_content_filter: Option<i32>,
|
||||||
//#[cfg_attr(feature = "sqlx", sqlx(try_from = "String"))]
|
//#[cfg_attr(feature = "sqlx", sqlx(try_from = "String"))]
|
||||||
pub features: Option<GuildFeaturesList>,
|
pub features: Option<GuildFeaturesList>,
|
||||||
|
@ -88,7 +88,7 @@ pub struct Guild {
|
||||||
pub region: Option<String>,
|
pub region: Option<String>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
#[cfg_attr(feature = "client", observe_option_vec)]
|
#[cfg_attr(feature = "client", observe_option_vec)]
|
||||||
pub roles: Option<Vec<Arc<RwLock<RoleObject>>>>,
|
pub roles: Option<Vec<Shared<RoleObject>>>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub rules_channel: Option<String>,
|
pub rules_channel: Option<String>,
|
||||||
pub rules_channel_id: Option<Snowflake>,
|
pub rules_channel_id: Option<Snowflake>,
|
||||||
|
@ -102,10 +102,10 @@ pub struct Guild {
|
||||||
pub verification_level: Option<VerificationLevel>,
|
pub verification_level: Option<VerificationLevel>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
#[cfg_attr(feature = "client", observe_option_vec)]
|
#[cfg_attr(feature = "client", observe_option_vec)]
|
||||||
pub voice_states: Option<Vec<Arc<RwLock<VoiceState>>>>,
|
pub voice_states: Option<Vec<Shared<VoiceState>>>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
#[cfg_attr(feature = "client", observe_option_vec)]
|
#[cfg_attr(feature = "client", observe_option_vec)]
|
||||||
pub webhooks: Option<Vec<Arc<RwLock<Webhook>>>>,
|
pub webhooks: Option<Vec<Shared<Webhook>>>,
|
||||||
#[cfg(feature = "sqlx")]
|
#[cfg(feature = "sqlx")]
|
||||||
pub welcome_screen: Option<sqlx::types::Json<WelcomeScreenObject>>,
|
pub welcome_screen: Option<sqlx::types::Json<WelcomeScreenObject>>,
|
||||||
#[cfg(not(feature = "sqlx"))]
|
#[cfg(not(feature = "sqlx"))]
|
||||||
|
@ -217,8 +217,6 @@ impl std::cmp::PartialEq for Guild {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::cmp::Eq for Guild {}
|
|
||||||
|
|
||||||
/// See <https://docs.spacebar.chat/routes/#get-/guilds/-guild_id-/bans/-user->
|
/// See <https://docs.spacebar.chat/routes/#get-/guilds/-guild_id-/bans/-user->
|
||||||
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, Hash)]
|
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq, Hash)]
|
||||||
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
|
#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))]
|
||||||
|
@ -239,11 +237,11 @@ pub struct GuildInvite {
|
||||||
pub created_at: DateTime<Utc>,
|
pub created_at: DateTime<Utc>,
|
||||||
pub expires_at: Option<DateTime<Utc>>,
|
pub expires_at: Option<DateTime<Utc>>,
|
||||||
pub guild_id: Snowflake,
|
pub guild_id: Snowflake,
|
||||||
pub guild: Option<Arc<RwLock<Guild>>>,
|
pub guild: Option<Shared<Guild>>,
|
||||||
pub channel_id: Snowflake,
|
pub channel_id: Snowflake,
|
||||||
pub channel: Option<Arc<RwLock<Channel>>>,
|
pub channel: Option<Shared<Channel>>,
|
||||||
pub inviter_id: Option<Snowflake>,
|
pub inviter_id: Option<Snowflake>,
|
||||||
pub inviter: Option<Arc<RwLock<User>>>,
|
pub inviter: Option<Shared<User>>,
|
||||||
pub target_user_id: Option<Snowflake>,
|
pub target_user_id: Option<Snowflake>,
|
||||||
pub target_user: Option<String>,
|
pub target_user: Option<String>,
|
||||||
pub target_user_type: Option<i32>,
|
pub target_user_type: Option<i32>,
|
||||||
|
@ -296,7 +294,7 @@ pub struct GuildScheduledEvent {
|
||||||
pub entity_type: GuildScheduledEventEntityType,
|
pub entity_type: GuildScheduledEventEntityType,
|
||||||
pub entity_id: Option<Snowflake>,
|
pub entity_id: Option<Snowflake>,
|
||||||
pub entity_metadata: Option<GuildScheduledEventEntityMetadata>,
|
pub entity_metadata: Option<GuildScheduledEventEntityMetadata>,
|
||||||
pub creator: Option<Arc<RwLock<User>>>,
|
pub creator: Option<Shared<User>>,
|
||||||
pub user_count: Option<u64>,
|
pub user_count: Option<u64>,
|
||||||
pub image: Option<String>,
|
pub image: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
use crate::types::{entities::PublicUser, Snowflake};
|
use crate::types::{entities::PublicUser, Snowflake};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Default, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Default, Serialize, Clone)]
|
||||||
|
@ -10,7 +9,7 @@ use crate::types::{entities::PublicUser, Snowflake};
|
||||||
/// # Reference
|
/// # Reference
|
||||||
/// See <https://discord-userdoccers.vercel.app/resources/guild#guild-member-object>
|
/// See <https://discord-userdoccers.vercel.app/resources/guild#guild-member-object>
|
||||||
pub struct GuildMember {
|
pub struct GuildMember {
|
||||||
pub user: Option<Arc<RwLock<PublicUser>>>,
|
pub user: Option<Shared<PublicUser>>,
|
||||||
pub nick: Option<String>,
|
pub nick: Option<String>,
|
||||||
pub avatar: Option<String>,
|
pub avatar: Option<String>,
|
||||||
pub roles: Vec<Snowflake>,
|
pub roles: Vec<Snowflake>,
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
entities::{Application, User},
|
entities::{Application, User},
|
||||||
utils::Snowflake,
|
utils::Snowflake,
|
||||||
|
@ -23,14 +22,14 @@ pub struct Integration {
|
||||||
pub expire_behaviour: Option<u8>,
|
pub expire_behaviour: Option<u8>,
|
||||||
pub expire_grace_period: Option<u16>,
|
pub expire_grace_period: Option<u16>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub user: Option<Arc<RwLock<User>>>,
|
pub user: Option<Shared<User>>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub account: IntegrationAccount,
|
pub account: IntegrationAccount,
|
||||||
pub synced_at: Option<DateTime<Utc>>,
|
pub synced_at: Option<DateTime<Utc>>,
|
||||||
pub subscriber_count: Option<f64>,
|
pub subscriber_count: Option<f64>,
|
||||||
pub revoked: Option<bool>,
|
pub revoked: Option<bool>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub application: Option<Arc<RwLock<Application>>>,
|
pub application: Option<Shared<Application>>,
|
||||||
pub scopes: Option<Vec<String>>,
|
pub scopes: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
use crate::types::{Snowflake, WelcomeScreenObject};
|
use crate::types::{Snowflake, WelcomeScreenObject};
|
||||||
|
|
||||||
use super::guild::GuildScheduledEvent;
|
use super::guild::GuildScheduledEvent;
|
||||||
|
@ -21,7 +20,7 @@ pub struct Invite {
|
||||||
pub flags: Option<i32>,
|
pub flags: Option<i32>,
|
||||||
pub guild: Option<InviteGuild>,
|
pub guild: Option<InviteGuild>,
|
||||||
pub guild_id: Option<Snowflake>,
|
pub guild_id: Option<Snowflake>,
|
||||||
pub guild_scheduled_event: Option<Arc<RwLock<GuildScheduledEvent>>>,
|
pub guild_scheduled_event: Option<Shared<GuildScheduledEvent>>,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub invite_type: Option<i32>,
|
pub invite_type: Option<i32>,
|
||||||
pub inviter: Option<User>,
|
pub inviter: Option<User>,
|
||||||
|
@ -59,7 +58,7 @@ pub struct InviteGuild {
|
||||||
/// See <https://discord-userdoccers.vercel.app/resources/invite#invite-stage-instance-object>
|
/// See <https://discord-userdoccers.vercel.app/resources/invite#invite-stage-instance-object>
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct InviteStageInstance {
|
pub struct InviteStageInstance {
|
||||||
pub members: Vec<Arc<RwLock<GuildMember>>>,
|
pub members: Vec<Shared<GuildMember>>,
|
||||||
pub participant_count: i32,
|
pub participant_count: i32,
|
||||||
pub speaker_count: i32,
|
pub speaker_count: i32,
|
||||||
pub topic: String,
|
pub topic: String,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
entities::{
|
entities::{
|
||||||
Application, Attachment, Channel, Emoji, GuildMember, PublicUser, RoleSubscriptionData,
|
Application, Attachment, Channel, Emoji, GuildMember, PublicUser, RoleSubscriptionData,
|
||||||
|
@ -121,7 +120,7 @@ pub struct MessageInteraction {
|
||||||
pub interaction_type: u8,
|
pub interaction_type: u8,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub user: User,
|
pub user: User,
|
||||||
pub member: Option<Arc<RwLock<GuildMember>>>,
|
pub member: Option<Shared<GuildMember>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, Eq, PartialOrd, Ord)]
|
||||||
|
@ -219,7 +218,7 @@ pub struct EmbedField {
|
||||||
inline: Option<bool>,
|
inline: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialOrd, PartialEq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
pub struct Reaction {
|
pub struct Reaction {
|
||||||
pub count: u32,
|
pub count: u32,
|
||||||
pub burst_count: u32,
|
pub burst_count: u32,
|
||||||
|
|
|
@ -23,6 +23,7 @@ pub use user_settings::*;
|
||||||
pub use voice_state::*;
|
pub use voice_state::*;
|
||||||
pub use webhook::*;
|
pub use webhook::*;
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use crate::gateway::Updateable;
|
use crate::gateway::Updateable;
|
||||||
|
|
||||||
|
@ -34,7 +35,6 @@ use async_trait::async_trait;
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
|
@ -69,9 +69,9 @@ pub trait Composite<T: Updateable + Clone + Debug> {
|
||||||
async fn watch_whole(self, gateway: &GatewayHandle) -> Self;
|
async fn watch_whole(self, gateway: &GatewayHandle) -> Self;
|
||||||
|
|
||||||
async fn option_observe_fn(
|
async fn option_observe_fn(
|
||||||
value: Option<Arc<RwLock<T>>>,
|
value: Option<Shared<T>>,
|
||||||
gateway: &GatewayHandle,
|
gateway: &GatewayHandle,
|
||||||
) -> Option<Arc<RwLock<T>>>
|
) -> Option<Shared<T>>
|
||||||
where
|
where
|
||||||
T: Composite<T> + Debug,
|
T: Composite<T> + Debug,
|
||||||
{
|
{
|
||||||
|
@ -84,9 +84,9 @@ pub trait Composite<T: Updateable + Clone + Debug> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn option_vec_observe_fn(
|
async fn option_vec_observe_fn(
|
||||||
value: Option<Vec<Arc<RwLock<T>>>>,
|
value: Option<Vec<Shared<T>>>,
|
||||||
gateway: &GatewayHandle,
|
gateway: &GatewayHandle,
|
||||||
) -> Option<Vec<Arc<RwLock<T>>>>
|
) -> Option<Vec<Shared<T>>>
|
||||||
where
|
where
|
||||||
T: Composite<T>,
|
T: Composite<T>,
|
||||||
{
|
{
|
||||||
|
@ -101,17 +101,14 @@ pub trait Composite<T: Updateable + Clone + Debug> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn value_observe_fn(value: Arc<RwLock<T>>, gateway: &GatewayHandle) -> Arc<RwLock<T>>
|
async fn value_observe_fn(value: Shared<T>, gateway: &GatewayHandle) -> Shared<T>
|
||||||
where
|
where
|
||||||
T: Composite<T>,
|
T: Composite<T>,
|
||||||
{
|
{
|
||||||
gateway.observe(value).await
|
gateway.observe(value).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn vec_observe_fn(
|
async fn vec_observe_fn(value: Vec<Shared<T>>, gateway: &GatewayHandle) -> Vec<Shared<T>>
|
||||||
value: Vec<Arc<RwLock<T>>>,
|
|
||||||
gateway: &GatewayHandle,
|
|
||||||
) -> Vec<Arc<RwLock<T>>>
|
|
||||||
where
|
where
|
||||||
T: Composite<T>,
|
T: Composite<T>,
|
||||||
{
|
{
|
||||||
|
@ -122,3 +119,19 @@ pub trait Composite<T: Updateable + Clone + Debug> {
|
||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait IntoShared {
|
||||||
|
/// Uses [`Shared`] to provide an ergonomic alternative to `Arc::new(RwLock::new(obj))`.
|
||||||
|
///
|
||||||
|
/// [`Shared<Self>`] can then be observed using the [`Gateway`], turning the underlying
|
||||||
|
/// `dyn Composite<Self>` into a self-updating struct, which is a tracked variant of a chorus
|
||||||
|
/// entity struct, updating its' held information when new information concerning itself arrives
|
||||||
|
/// over the [`Gateway`] connection, reducing the need for expensive network-API calls.
|
||||||
|
fn into_shared(self) -> Shared<Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Sized> IntoShared for T {
|
||||||
|
fn into_shared(self) -> Shared<Self> {
|
||||||
|
Arc::new(RwLock::new(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_repr::{Deserialize_repr, Serialize_repr};
|
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
use crate::types::Snowflake;
|
use crate::types::Snowflake;
|
||||||
|
|
||||||
use super::PublicUser;
|
use super::PublicUser;
|
||||||
|
@ -15,7 +14,7 @@ pub struct Relationship {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub relationship_type: RelationshipType,
|
pub relationship_type: RelationshipType,
|
||||||
pub nickname: Option<String>,
|
pub nickname: Option<String>,
|
||||||
pub user: Arc<RwLock<PublicUser>>,
|
pub user: Shared<PublicUser>,
|
||||||
pub since: Option<DateTime<Utc>>,
|
pub since: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
use crate::types::{entities::User, utils::Snowflake};
|
use crate::types::{entities::User, utils::Snowflake};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
|
||||||
|
@ -24,7 +23,7 @@ pub struct Sticker {
|
||||||
pub available: Option<bool>,
|
pub available: Option<bool>,
|
||||||
pub guild_id: Option<Snowflake>,
|
pub guild_id: Option<Snowflake>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub user: Option<Arc<RwLock<User>>>,
|
pub user: Option<Shared<User>>,
|
||||||
pub sort_value: Option<u8>,
|
pub sort_value: Option<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
use crate::types::entities::User;
|
use crate::types::entities::User;
|
||||||
use crate::types::Snowflake;
|
use crate::types::Snowflake;
|
||||||
|
|
||||||
|
@ -21,5 +20,5 @@ pub struct TeamMember {
|
||||||
pub membership_state: u8,
|
pub membership_state: u8,
|
||||||
pub permissions: Vec<String>,
|
pub permissions: Vec<String>,
|
||||||
pub team_id: Snowflake,
|
pub team_id: Snowflake,
|
||||||
pub user: Arc<RwLock<User>>,
|
pub user: Shared<User>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
entities::{Guild, User},
|
entities::{Guild, User},
|
||||||
utils::Snowflake,
|
utils::Snowflake,
|
||||||
|
@ -18,13 +17,13 @@ pub struct GuildTemplate {
|
||||||
pub usage_count: Option<u64>,
|
pub usage_count: Option<u64>,
|
||||||
pub creator_id: Snowflake,
|
pub creator_id: Snowflake,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub creator: Arc<RwLock<User>>,
|
pub creator: Shared<User>,
|
||||||
pub created_at: DateTime<Utc>,
|
pub created_at: DateTime<Utc>,
|
||||||
pub updated_at: DateTime<Utc>,
|
pub updated_at: DateTime<Utc>,
|
||||||
pub source_guild_id: Snowflake,
|
pub source_guild_id: Snowflake,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub source_guild: Vec<Arc<RwLock<Guild>>>,
|
pub source_guild: Vec<Shared<Guild>>,
|
||||||
// Unsure how a {recursive: Guild} looks like, might be a Vec?
|
// Unsure how a {recursive: Guild} looks like, might be a Vec?
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub serialized_source_guild: Vec<Arc<RwLock<Guild>>>,
|
pub serialized_source_guild: Vec<Shared<Guild>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub struct UserData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl User {
|
impl User {
|
||||||
pub fn to_public_user(self) -> PublicUser {
|
pub fn into_public_user(self) -> PublicUser {
|
||||||
PublicUser::from(self)
|
PublicUser::from(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ bitflags::bitflags! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd)]
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
|
||||||
pub struct UserProfileMetadata {
|
pub struct UserProfileMetadata {
|
||||||
pub guild_id: Option<Snowflake>,
|
pub guild_id: Option<Snowflake>,
|
||||||
pub pronouns: String,
|
pub pronouns: String,
|
||||||
|
|
|
@ -3,6 +3,8 @@ use std::sync::{Arc, RwLock};
|
||||||
use chrono::{serde::ts_milliseconds_option, Utc};
|
use chrono::{serde::ts_milliseconds_option, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||||
#[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
|
#[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
|
@ -77,7 +79,7 @@ pub struct UserSettings {
|
||||||
#[cfg(not(feature = "sqlx"))]
|
#[cfg(not(feature = "sqlx"))]
|
||||||
pub restricted_guilds: Vec<String>,
|
pub restricted_guilds: Vec<String>,
|
||||||
pub show_current_game: bool,
|
pub show_current_game: bool,
|
||||||
pub status: Arc<RwLock<UserStatus>>,
|
pub status: Shared<UserStatus>,
|
||||||
pub stream_notifications_enabled: bool,
|
pub stream_notifications_enabled: bool,
|
||||||
pub theme: UserTheme,
|
pub theme: UserTheme,
|
||||||
pub timezone_offset: i16,
|
pub timezone_offset: i16,
|
||||||
|
@ -153,5 +155,5 @@ pub struct GuildFolder {
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct LoginResult {
|
pub struct LoginResult {
|
||||||
pub token: String,
|
pub token: String,
|
||||||
pub settings: Arc<RwLock<UserSettings>>,
|
pub settings: Shared<UserSettings>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use chorus_macros::Composite;
|
use chorus_macros::Composite;
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use crate::types::Composite;
|
use crate::types::Composite;
|
||||||
|
|
||||||
|
@ -33,7 +32,7 @@ pub struct VoiceState {
|
||||||
pub guild: Option<Guild>,
|
pub guild: Option<Guild>,
|
||||||
pub channel_id: Option<Snowflake>,
|
pub channel_id: Option<Snowflake>,
|
||||||
pub user_id: Snowflake,
|
pub user_id: Snowflake,
|
||||||
pub member: Option<Arc<RwLock<GuildMember>>>,
|
pub member: Option<Shared<GuildMember>>,
|
||||||
/// Includes alphanumeric characters, not a snowflake
|
/// Includes alphanumeric characters, not a snowflake
|
||||||
pub session_id: String,
|
pub session_id: String,
|
||||||
pub token: Option<String>,
|
pub token: Option<String>,
|
||||||
|
@ -49,6 +48,7 @@ pub struct VoiceState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Updateable for VoiceState {
|
impl Updateable for VoiceState {
|
||||||
|
#[cfg(not(tarpaulin_include))]
|
||||||
fn id(&self) -> Snowflake {
|
fn id(&self) -> Snowflake {
|
||||||
if let Some(id) = self.id {
|
if let Some(id) = self.id {
|
||||||
id // ID exists: Only the case for Spacebar Server impls
|
id // ID exists: Only the case for Spacebar Server impls
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::gateway::Shared;
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use crate::gateway::Updateable;
|
use crate::gateway::Updateable;
|
||||||
|
|
||||||
|
@ -36,10 +36,10 @@ pub struct Webhook {
|
||||||
pub application_id: Snowflake,
|
pub application_id: Snowflake,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub user: Option<Arc<RwLock<User>>>,
|
pub user: Option<Shared<User>>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub source_guild: Option<Arc<RwLock<Guild>>>,
|
pub source_guild: Option<Shared<Guild>>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub url: Option<String>,
|
pub url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,9 @@ pub struct AutoModerationRuleUpdate {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
|
#[cfg(not(tarpaulin_include))]
|
||||||
impl UpdateMessage<AutoModerationRule> for AutoModerationRuleUpdate {
|
impl UpdateMessage<AutoModerationRule> for AutoModerationRuleUpdate {
|
||||||
|
#[cfg(not(tarpaulin_include))]
|
||||||
fn id(&self) -> Option<Snowflake> {
|
fn id(&self) -> Option<Snowflake> {
|
||||||
Some(self.rule.id)
|
Some(self.rule.id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::types::events::WebSocketEvent;
|
use crate::types::events::WebSocketEvent;
|
||||||
|
use crate::types::IntoShared;
|
||||||
use crate::types::{entities::Channel, JsonField, Snowflake, SourceUrlField};
|
use crate::types::{entities::Channel, JsonField, Snowflake, SourceUrlField};
|
||||||
use chorus_macros::{JsonField, SourceUrlField};
|
use chorus_macros::{JsonField, SourceUrlField};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
|
@ -8,7 +9,7 @@ use serde::{Deserialize, Serialize};
|
||||||
use super::UpdateMessage;
|
use super::UpdateMessage;
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use std::sync::{Arc, RwLock};
|
use crate::gateway::Shared;
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use crate::types::Guild;
|
use crate::types::Guild;
|
||||||
|
@ -38,13 +39,14 @@ impl WebSocketEvent for ChannelCreate {}
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
impl UpdateMessage<Guild> for ChannelCreate {
|
impl UpdateMessage<Guild> for ChannelCreate {
|
||||||
|
#[cfg(not(tarpaulin_include))]
|
||||||
fn id(&self) -> Option<Snowflake> {
|
fn id(&self) -> Option<Snowflake> {
|
||||||
self.channel.guild_id
|
self.channel.guild_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, object_to_update: Arc<RwLock<Guild>>) {
|
fn update(&mut self, object_to_update: Shared<Guild>) {
|
||||||
let mut write = object_to_update.write().unwrap();
|
let mut write = object_to_update.write().unwrap();
|
||||||
let update = Arc::new(RwLock::new(self.channel.clone()));
|
let update = self.channel.clone().into_shared();
|
||||||
if write.channels.is_some() {
|
if write.channels.is_some() {
|
||||||
write.channels.as_mut().unwrap().push(update);
|
write.channels.as_mut().unwrap().push(update);
|
||||||
} else {
|
} else {
|
||||||
|
@ -68,10 +70,12 @@ impl WebSocketEvent for ChannelUpdate {}
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
impl UpdateMessage<Channel> for ChannelUpdate {
|
impl UpdateMessage<Channel> for ChannelUpdate {
|
||||||
fn update(&mut self, object_to_update: Arc<RwLock<Channel>>) {
|
fn update(&mut self, object_to_update: Shared<Channel>) {
|
||||||
let mut write = object_to_update.write().unwrap();
|
let mut write = object_to_update.write().unwrap();
|
||||||
*write = self.channel.clone();
|
*write = self.channel.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(tarpaulin_include))]
|
||||||
fn id(&self) -> Option<Snowflake> {
|
fn id(&self) -> Option<Snowflake> {
|
||||||
Some(self.channel.id)
|
Some(self.channel.id)
|
||||||
}
|
}
|
||||||
|
@ -110,11 +114,12 @@ pub struct ChannelDelete {
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
impl UpdateMessage<Guild> for ChannelDelete {
|
impl UpdateMessage<Guild> for ChannelDelete {
|
||||||
|
#[cfg(not(tarpaulin_include))]
|
||||||
fn id(&self) -> Option<Snowflake> {
|
fn id(&self) -> Option<Snowflake> {
|
||||||
self.channel.guild_id
|
self.channel.guild_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, object_to_update: Arc<RwLock<Guild>>) {
|
fn update(&mut self, object_to_update: Shared<Guild>) {
|
||||||
if self.id().is_none() {
|
if self.id().is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@ use serde::{Deserialize, Serialize};
|
||||||
use crate::types::entities::{Guild, PublicUser, UnavailableGuild};
|
use crate::types::entities::{Guild, PublicUser, UnavailableGuild};
|
||||||
use crate::types::events::WebSocketEvent;
|
use crate::types::events::WebSocketEvent;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
AuditLogEntry, Emoji, GuildMember, GuildScheduledEvent, JsonField, RoleObject, Snowflake,
|
AuditLogEntry, Emoji, GuildMember, GuildScheduledEvent, IntoShared, JsonField, RoleObject,
|
||||||
SourceUrlField, Sticker,
|
Snowflake, SourceUrlField, Sticker,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::PresenceUpdate;
|
use super::PresenceUpdate;
|
||||||
|
@ -14,7 +14,7 @@ use super::PresenceUpdate;
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use super::UpdateMessage;
|
use super::UpdateMessage;
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use std::sync::{Arc, RwLock};
|
use crate::gateway::Shared;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Default, Clone, SourceUrlField, JsonField)]
|
#[derive(Debug, Deserialize, Serialize, Default, Clone, SourceUrlField, JsonField)]
|
||||||
/// See <https://discord.com/developers/docs/topics/gateway-events#guild-create>;
|
/// See <https://discord.com/developers/docs/topics/gateway-events#guild-create>;
|
||||||
|
@ -30,7 +30,9 @@ pub struct GuildCreate {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
|
#[cfg(not(tarpaulin_include))]
|
||||||
impl UpdateMessage<Guild> for GuildCreate {
|
impl UpdateMessage<Guild> for GuildCreate {
|
||||||
|
#[cfg(not(tarpaulin_include))]
|
||||||
fn id(&self) -> Option<Snowflake> {
|
fn id(&self) -> Option<Snowflake> {
|
||||||
match &self.d {
|
match &self.d {
|
||||||
GuildCreateDataOption::UnavailableGuild(unavailable) => Some(unavailable.id),
|
GuildCreateDataOption::UnavailableGuild(unavailable) => Some(unavailable.id),
|
||||||
|
@ -38,7 +40,7 @@ impl UpdateMessage<Guild> for GuildCreate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, _: Arc<RwLock<Guild>>) {}
|
fn update(&mut self, _: Shared<Guild>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
@ -92,6 +94,7 @@ impl WebSocketEvent for GuildUpdate {}
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
impl UpdateMessage<Guild> for GuildUpdate {
|
impl UpdateMessage<Guild> for GuildUpdate {
|
||||||
|
#[cfg(not(tarpaulin_include))]
|
||||||
fn id(&self) -> Option<Snowflake> {
|
fn id(&self) -> Option<Snowflake> {
|
||||||
Some(self.guild.id)
|
Some(self.guild.id)
|
||||||
}
|
}
|
||||||
|
@ -111,10 +114,11 @@ pub struct GuildDelete {
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
impl UpdateMessage<Guild> for GuildDelete {
|
impl UpdateMessage<Guild> for GuildDelete {
|
||||||
|
#[cfg(not(tarpaulin_include))]
|
||||||
fn id(&self) -> Option<Snowflake> {
|
fn id(&self) -> Option<Snowflake> {
|
||||||
Some(self.guild.id)
|
Some(self.guild.id)
|
||||||
}
|
}
|
||||||
fn update(&mut self, _: Arc<RwLock<Guild>>) {}
|
fn update(&mut self, _: Shared<Guild>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebSocketEvent for GuildDelete {}
|
impl WebSocketEvent for GuildDelete {}
|
||||||
|
@ -225,20 +229,21 @@ impl WebSocketEvent for GuildRoleCreate {}
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
impl UpdateMessage<Guild> for GuildRoleCreate {
|
impl UpdateMessage<Guild> for GuildRoleCreate {
|
||||||
|
#[cfg(not(tarpaulin_include))]
|
||||||
fn id(&self) -> Option<Snowflake> {
|
fn id(&self) -> Option<Snowflake> {
|
||||||
Some(self.guild_id)
|
Some(self.guild_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, object_to_update: Arc<RwLock<Guild>>) {
|
fn update(&mut self, object_to_update: Shared<Guild>) {
|
||||||
let mut object_to_update = object_to_update.write().unwrap();
|
let mut object_to_update = object_to_update.write().unwrap();
|
||||||
if object_to_update.roles.is_some() {
|
if object_to_update.roles.is_some() {
|
||||||
object_to_update
|
object_to_update
|
||||||
.roles
|
.roles
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.push(Arc::new(RwLock::new(self.role.clone())));
|
.push(self.role.clone().into_shared());
|
||||||
} else {
|
} else {
|
||||||
object_to_update.roles = Some(Vec::from([Arc::new(RwLock::new(self.role.clone()))]));
|
object_to_update.roles = Some(Vec::from([self.role.clone().into_shared()]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,11 +263,12 @@ impl WebSocketEvent for GuildRoleUpdate {}
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
impl UpdateMessage<RoleObject> for GuildRoleUpdate {
|
impl UpdateMessage<RoleObject> for GuildRoleUpdate {
|
||||||
|
#[cfg(not(tarpaulin_include))]
|
||||||
fn id(&self) -> Option<Snowflake> {
|
fn id(&self) -> Option<Snowflake> {
|
||||||
Some(self.role.id)
|
Some(self.role.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, object_to_update: Arc<RwLock<RoleObject>>) {
|
fn update(&mut self, object_to_update: Shared<RoleObject>) {
|
||||||
let mut write = object_to_update.write().unwrap();
|
let mut write = object_to_update.write().unwrap();
|
||||||
*write = self.role.clone();
|
*write = self.role.clone();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,9 @@ use serde_json::{from_str, from_value, to_value, Value};
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use std::fmt::Debug;
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use std::sync::{Arc, RwLock};
|
use crate::gateway::Shared;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
@ -132,9 +132,10 @@ pub(crate) trait UpdateMessage<T>: Clone + JsonField + SourceUrlField
|
||||||
where
|
where
|
||||||
T: Updateable + Serialize + DeserializeOwned + Clone,
|
T: Updateable + Serialize + DeserializeOwned + Clone,
|
||||||
{
|
{
|
||||||
fn update(&mut self, object_to_update: Arc<RwLock<T>>) {
|
fn update(&mut self, object_to_update: Shared<T>) {
|
||||||
update_object(self.get_json(), object_to_update)
|
update_object(self.get_json(), object_to_update)
|
||||||
}
|
}
|
||||||
|
#[cfg(not(tarpaulin_include))]
|
||||||
fn id(&self) -> Option<Snowflake>;
|
fn id(&self) -> Option<Snowflake>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +153,7 @@ pub trait SourceUrlField: Clone {
|
||||||
/// Only applicable for events where the Update struct is the same as the Entity struct
|
/// Only applicable for events where the Update struct is the same as the Entity struct
|
||||||
pub(crate) fn update_object(
|
pub(crate) fn update_object(
|
||||||
value: String,
|
value: String,
|
||||||
object: Arc<RwLock<(impl Updateable + Serialize + DeserializeOwned + Clone)>>,
|
object: Shared<(impl Updateable + Serialize + DeserializeOwned + Clone)>,
|
||||||
) {
|
) {
|
||||||
let data_from_event: HashMap<String, Value> = from_str(&value).unwrap();
|
let data_from_event: HashMap<String, Value> = from_str(&value).unwrap();
|
||||||
let mut original_data: HashMap<String, Value> =
|
let mut original_data: HashMap<String, Value> =
|
||||||
|
|
|
@ -32,6 +32,7 @@ impl WebSocketEvent for ThreadUpdate {}
|
||||||
|
|
||||||
#[cfg(feature = "client")]
|
#[cfg(feature = "client")]
|
||||||
impl UpdateMessage<Channel> for ThreadUpdate {
|
impl UpdateMessage<Channel> for ThreadUpdate {
|
||||||
|
#[cfg(not(tarpaulin_include))]
|
||||||
fn id(&self) -> Option<Snowflake> {
|
fn id(&self) -> Option<Snowflake> {
|
||||||
Some(self.thread.id)
|
Some(self.thread.id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ impl std::default::Default for GetUserGuildSchema {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, PartialOrd)]
|
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)]
|
||||||
pub struct GuildPreview {
|
pub struct GuildPreview {
|
||||||
pub id: Snowflake,
|
pub id: Snowflake,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
|
@ -111,7 +111,8 @@ impl Observer<VoiceReady> for VoiceHandler {
|
||||||
|
|
||||||
*self.voice_udp_connection.lock().await = Some(udp_handle.clone());
|
*self.voice_udp_connection.lock().await = Some(udp_handle.clone());
|
||||||
|
|
||||||
let string_ip_address = String::from_utf8(ip_discovery.address).expect("Ip discovery gave non string ip");
|
let string_ip_address =
|
||||||
|
String::from_utf8(ip_discovery.address).expect("Ip discovery gave non string ip");
|
||||||
|
|
||||||
self.voice_gateway_connection
|
self.voice_gateway_connection
|
||||||
.lock()
|
.lock()
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::sync::{Arc, RwLock};
|
use chorus::gateway::{Gateway, Shared};
|
||||||
|
use chorus::types::IntoShared;
|
||||||
use chorus::gateway::Gateway;
|
|
||||||
use chorus::{
|
use chorus::{
|
||||||
instance::{ChorusUser, Instance},
|
instance::{ChorusUser, Instance},
|
||||||
types::{
|
types::{
|
||||||
|
@ -16,9 +15,9 @@ pub(crate) struct TestBundle {
|
||||||
pub urls: UrlBundle,
|
pub urls: UrlBundle,
|
||||||
pub user: ChorusUser,
|
pub user: ChorusUser,
|
||||||
pub instance: Instance,
|
pub instance: Instance,
|
||||||
pub guild: Arc<RwLock<Guild>>,
|
pub guild: Shared<Guild>,
|
||||||
pub role: Arc<RwLock<RoleObject>>,
|
pub role: Shared<RoleObject>,
|
||||||
pub channel: Arc<RwLock<Channel>>,
|
pub channel: Shared<Channel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
@ -119,9 +118,9 @@ pub(crate) async fn setup() -> TestBundle {
|
||||||
urls,
|
urls,
|
||||||
user,
|
user,
|
||||||
instance,
|
instance,
|
||||||
guild: Arc::new(RwLock::new(guild)),
|
guild: guild.into_shared(),
|
||||||
role: Arc::new(RwLock::new(role)),
|
role: role.into_shared(),
|
||||||
channel: Arc::new(RwLock::new(channel)),
|
channel: channel.into_shared(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
mod common;
|
mod common;
|
||||||
|
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use chorus::errors::GatewayError;
|
use chorus::errors::GatewayError;
|
||||||
use chorus::gateway::*;
|
use chorus::gateway::*;
|
||||||
use chorus::types::{self, ChannelModifySchema, GatewayReady, RoleCreateModifySchema, RoleObject};
|
use chorus::types::{
|
||||||
|
self, Channel, ChannelCreateSchema, ChannelModifySchema, GatewayReady, IntoShared,
|
||||||
|
RoleCreateModifySchema, RoleObject,
|
||||||
|
};
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use wasm_bindgen_test::*;
|
use wasm_bindgen_test::*;
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
@ -82,7 +85,10 @@ async fn test_gateway_authenticate() {
|
||||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||||
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
|
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
|
||||||
async fn test_self_updating_structs() {
|
async fn test_self_updating_structs() {
|
||||||
|
// PRETTYFYME: This test is a bit of a mess, but it works. Ideally, each self-updating struct
|
||||||
|
// would have its own test.
|
||||||
let mut bundle = common::setup().await;
|
let mut bundle = common::setup().await;
|
||||||
|
|
||||||
let received_channel = bundle
|
let received_channel = bundle
|
||||||
.user
|
.user
|
||||||
.gateway
|
.gateway
|
||||||
|
@ -110,6 +116,34 @@ async fn test_self_updating_structs() {
|
||||||
"selfupdating".to_string()
|
"selfupdating".to_string()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let guild = bundle
|
||||||
|
.user
|
||||||
|
.gateway
|
||||||
|
.observe_and_into_inner(bundle.guild.clone())
|
||||||
|
.await;
|
||||||
|
assert!(guild.channels.is_none());
|
||||||
|
|
||||||
|
Channel::create(
|
||||||
|
&mut bundle.user,
|
||||||
|
guild.id,
|
||||||
|
None,
|
||||||
|
ChannelCreateSchema {
|
||||||
|
name: "selfupdating2".to_string(),
|
||||||
|
channel_type: Some(types::ChannelType::GuildText),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let guild = bundle
|
||||||
|
.user
|
||||||
|
.gateway
|
||||||
|
.observe_and_into_inner(guild.into_shared())
|
||||||
|
.await;
|
||||||
|
assert!(guild.channels.is_some());
|
||||||
|
assert!(guild.channels.as_ref().unwrap().len() == 1);
|
||||||
|
|
||||||
common::teardown(bundle).await
|
common::teardown(bundle).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +178,7 @@ async fn test_recursive_self_updating_structs() {
|
||||||
bundle
|
bundle
|
||||||
.user
|
.user
|
||||||
.gateway
|
.gateway
|
||||||
.observe(Arc::new(RwLock::new(role.clone())))
|
.observe(role.clone().into_shared())
|
||||||
.await;
|
.await;
|
||||||
// Update Guild and check for Guild
|
// Update Guild and check for Guild
|
||||||
let inner_guild = guild.read().unwrap().clone();
|
let inner_guild = guild.read().unwrap().clone();
|
||||||
|
@ -157,7 +191,7 @@ async fn test_recursive_self_updating_structs() {
|
||||||
let role_inner = bundle
|
let role_inner = bundle
|
||||||
.user
|
.user
|
||||||
.gateway
|
.gateway
|
||||||
.observe_and_into_inner(Arc::new(RwLock::new(role.clone())))
|
.observe_and_into_inner(role.clone().into_shared())
|
||||||
.await;
|
.await;
|
||||||
assert_eq!(role_inner.name, "yippieee");
|
assert_eq!(role_inner.name, "yippieee");
|
||||||
// Check if the change propagated
|
// Check if the change propagated
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
use chorus::ratelimiter::ChorusRequest;
|
||||||
|
|
||||||
|
mod common;
|
||||||
|
|
||||||
|
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||||
|
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
|
||||||
|
async fn get_limit_config() {
|
||||||
|
let conf = ChorusRequest::get_limits_config("http://localhost:3001/api")
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert!(conf.channel.max_pins > 0);
|
||||||
|
assert!(conf.channel.max_topic > 0);
|
||||||
|
assert!(conf.channel.max_webhooks > 0);
|
||||||
|
assert!(conf.guild.max_roles > 0);
|
||||||
|
assert!(conf.guild.max_channels > 0);
|
||||||
|
assert!(conf.guild.max_emojis > 0);
|
||||||
|
assert!(conf.guild.max_channels_in_category > 0);
|
||||||
|
assert!(conf.guild.max_members > 0);
|
||||||
|
assert!(conf.message.max_attachment_size > 0);
|
||||||
|
assert!(conf.message.max_bulk_delete > 0);
|
||||||
|
assert!(conf.message.max_reactions > 0);
|
||||||
|
assert!(conf.message.max_characters > 0);
|
||||||
|
assert!(conf.message.max_tts_characters == 0);
|
||||||
|
assert!(conf.user.max_guilds > 0);
|
||||||
|
assert!(conf.user.max_friends > 0);
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,18 @@
|
||||||
|
use chorus::types::{PublicUser, Snowflake, User};
|
||||||
|
|
||||||
|
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||||
|
#[cfg_attr(not(target_arch = "wasm32"), test)]
|
||||||
|
fn to_public_user() {
|
||||||
|
let mut user = User::default();
|
||||||
|
let mut public_user = PublicUser {
|
||||||
|
username: Some("".to_string()),
|
||||||
|
discriminator: Some("".to_string()),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let id: Snowflake = 1_u64.into();
|
||||||
|
user.id = id;
|
||||||
|
public_user.id = id;
|
||||||
|
|
||||||
|
let from_user = user.into_public_user();
|
||||||
|
assert_eq!(public_user, from_user);
|
||||||
|
}
|
Loading…
Reference in New Issue