add types from polyphony-types
This commit is contained in:
parent
77b624e894
commit
d1b72a583f
|
@ -0,0 +1,187 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::{Map, Value};
|
||||||
|
|
||||||
|
pub use crate::{
|
||||||
|
config::types::{
|
||||||
|
api_configuration::ApiConfiguration, cdn_configuration::CdnConfiguration,
|
||||||
|
defaults_configuration::DefaultsConfiguration, email_configuration::EmailConfiguration,
|
||||||
|
endpoint_configuration::EndpointConfiguration,
|
||||||
|
external_tokens_configuration::ExternalTokensConfiguration,
|
||||||
|
general_configuration::GeneralConfiguration, gif_configuration::GifConfiguration,
|
||||||
|
guild_configuration::GuildConfiguration, kafka_configuration::KafkaConfiguration,
|
||||||
|
limit_configuration::LimitsConfiguration, login_configuration::LoginConfiguration,
|
||||||
|
metrics_configuration::MetricsConfiguration,
|
||||||
|
password_reset_configuration::PasswordResetConfiguration,
|
||||||
|
rabbit_mq_configuration::RabbitMQConfiguration, region_configuration::RegionConfiguration,
|
||||||
|
register_configuration::RegisterConfiguration,
|
||||||
|
security_configuration::SecurityConfiguration, sentry_configuration::SentryConfiguration,
|
||||||
|
template_configuration::TemplateConfiguration,
|
||||||
|
},
|
||||||
|
entities::ConfigEntity,
|
||||||
|
};
|
||||||
|
|
||||||
|
mod types;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ConfigValue {
|
||||||
|
pub gateway: EndpointConfiguration,
|
||||||
|
pub cdn: CdnConfiguration,
|
||||||
|
pub api: ApiConfiguration,
|
||||||
|
pub general: GeneralConfiguration,
|
||||||
|
pub limits: LimitsConfiguration,
|
||||||
|
pub security: SecurityConfiguration,
|
||||||
|
pub login: LoginConfiguration,
|
||||||
|
pub register: RegisterConfiguration,
|
||||||
|
pub regions: RegionConfiguration,
|
||||||
|
pub guild: GuildConfiguration,
|
||||||
|
pub gif: GifConfiguration,
|
||||||
|
pub rabbitmq: RabbitMQConfiguration,
|
||||||
|
pub kafka: KafkaConfiguration,
|
||||||
|
pub templates: TemplateConfiguration,
|
||||||
|
pub metrics: MetricsConfiguration,
|
||||||
|
pub sentry: SentryConfiguration,
|
||||||
|
pub defaults: DefaultsConfiguration,
|
||||||
|
pub external: ExternalTokensConfiguration,
|
||||||
|
pub email: EmailConfiguration,
|
||||||
|
pub password_reset: PasswordResetConfiguration,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConfigValue {
|
||||||
|
pub fn to_pairs(&self) -> Vec<ConfigEntity> {
|
||||||
|
let v = serde_json::json!(self);
|
||||||
|
|
||||||
|
generate_pairs(&v, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_pairs(pairs: Vec<ConfigEntity>) -> Self {
|
||||||
|
pairs_to_config(pairs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_pairs(obj: &Value, key: &str) -> Vec<ConfigEntity> {
|
||||||
|
let mut pairs = Vec::new();
|
||||||
|
match obj {
|
||||||
|
Value::Object(map) => {
|
||||||
|
for (k, v) in map {
|
||||||
|
let new_key = if key.is_empty() {
|
||||||
|
k.to_string()
|
||||||
|
} else {
|
||||||
|
format!("{}_{}", key, k)
|
||||||
|
};
|
||||||
|
pairs.extend(generate_pairs(v, &new_key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Value::Array(arr) => {
|
||||||
|
for (i, v) in arr.iter().enumerate() {
|
||||||
|
let new_key = format!("{}_{}", key, i);
|
||||||
|
pairs.extend(generate_pairs(v, &new_key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => pairs.push(ConfigEntity {
|
||||||
|
key: key.to_string(),
|
||||||
|
value: Some(obj.clone()),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
pairs
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pairs_to_config(pairs: Vec<ConfigEntity>) -> ConfigValue {
|
||||||
|
let mut value = Value::Object(Map::new());
|
||||||
|
|
||||||
|
for p in pairs {
|
||||||
|
let keys: Vec<&str> = p.key.split('_').collect();
|
||||||
|
let mut path = vec![];
|
||||||
|
|
||||||
|
for (i, &key) in keys.iter().enumerate() {
|
||||||
|
path.push(key);
|
||||||
|
|
||||||
|
if i == keys.len() - 1 {
|
||||||
|
insert_into(&mut value, &path, p.value.clone().unwrap_or(Value::Null));
|
||||||
|
} else if keys[i+1].parse::<usize>().is_ok() {
|
||||||
|
if !path_exists(&value, &path) {
|
||||||
|
insert_into(&mut value, &path, Value::Array(Vec::new()));
|
||||||
|
}
|
||||||
|
} else if !path_exists(&value, &path) {
|
||||||
|
insert_into(&mut value, &path, Value::Object(Map::new()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
serde_json::from_value(value).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path_exists(value: &Value, path: &[&str]) -> bool {
|
||||||
|
let mut current = value;
|
||||||
|
|
||||||
|
for &key in path {
|
||||||
|
match current {
|
||||||
|
Value::Object(map) => {
|
||||||
|
if let Some(v) = map.get(key) {
|
||||||
|
current = v;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Value::Array(arr) => {
|
||||||
|
if let Ok(index) = key.parse::<usize>() {
|
||||||
|
if let Some(v) = arr.get(index) {
|
||||||
|
current = v;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => return false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_into(value: &mut Value, path: &[&str], new_value: Value) {
|
||||||
|
let last_key = path.last().unwrap();
|
||||||
|
let parent_path = &path[0..path.len()-1];
|
||||||
|
|
||||||
|
let mut current = value;
|
||||||
|
|
||||||
|
for &key in parent_path {
|
||||||
|
current = match current {
|
||||||
|
Value::Object(map) => map.get_mut(key).unwrap(),
|
||||||
|
Value::Array(arr) => arr.get_mut(key.parse::<usize>().unwrap()).unwrap(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
match current {
|
||||||
|
Value::Object(map) => {
|
||||||
|
map.insert((*last_key).to_string(), new_value);
|
||||||
|
},
|
||||||
|
Value::Array(arr) => {
|
||||||
|
let index = last_key.parse::<usize>().unwrap();
|
||||||
|
if index >= arr.len() {
|
||||||
|
arr.resize(index + 1, Value::Null);
|
||||||
|
}
|
||||||
|
arr[index] = new_value;
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::config::{generate_pairs, pairs_to_config, ConfigValue};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_pairs() {
|
||||||
|
let c = ConfigValue::default();
|
||||||
|
let v = serde_json::json!(&c);
|
||||||
|
|
||||||
|
let pairs = generate_pairs(&v, "");
|
||||||
|
|
||||||
|
let cfg = pairs_to_config(pairs);
|
||||||
|
assert_eq!(cfg, c)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ApiConfiguration {
|
||||||
|
pub default_version: String,
|
||||||
|
pub active_versions: Vec<String>,
|
||||||
|
pub endpoint_public: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ApiConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
default_version: String::from("9"),
|
||||||
|
active_versions: vec![
|
||||||
|
String::from("6"),
|
||||||
|
String::from("7"),
|
||||||
|
String::from("8"),
|
||||||
|
String::from("9"),
|
||||||
|
],
|
||||||
|
endpoint_public: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CdnConfiguration {
|
||||||
|
pub resize_height_max: u64,
|
||||||
|
pub resize_width_max: u64,
|
||||||
|
pub imagor_server_url: Option<String>,
|
||||||
|
|
||||||
|
pub endpoint_public: Option<String>,
|
||||||
|
pub endpoint_private: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for CdnConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
resize_height_max: 1000,
|
||||||
|
resize_width_max: 1000,
|
||||||
|
imagor_server_url: None,
|
||||||
|
|
||||||
|
endpoint_private: None,
|
||||||
|
endpoint_public: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config::types::subconfigs::defaults::{guild::GuildDefaults, user::UserDefaults};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DefaultsConfiguration {
|
||||||
|
pub guild: GuildDefaults,
|
||||||
|
pub user: UserDefaults,
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config::types::subconfigs::email::{
|
||||||
|
mailgun::MailGunConfiguration, mailjet::MailJetConfiguration, sendgrid::SendGridConfiguration,
|
||||||
|
smtp::SMTPConfiguration,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
|
||||||
|
pub enum EmailProvider {
|
||||||
|
Smtp,
|
||||||
|
MailGun,
|
||||||
|
MailJet,
|
||||||
|
SendGrid,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct EmailConfiguration {
|
||||||
|
pub provider: Option<EmailProvider>,
|
||||||
|
pub smtp: SMTPConfiguration,
|
||||||
|
pub mailgun: MailGunConfiguration,
|
||||||
|
pub mailjet: MailJetConfiguration,
|
||||||
|
pub sendgrid: SendGridConfiguration,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct EndpointConfiguration {
|
||||||
|
pub endpoint_client: Option<String>,
|
||||||
|
pub endpoint_private: Option<String>,
|
||||||
|
pub endpoint_public: Option<String>,
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ExternalTokensConfiguration {
|
||||||
|
pub twitter: Option<String>,
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::utils::Snowflake;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct GeneralConfiguration {
|
||||||
|
pub instance_name: String,
|
||||||
|
pub instance_description: Option<String>,
|
||||||
|
pub front_page: Option<String>,
|
||||||
|
pub tos_page: Option<String>,
|
||||||
|
pub correspondence_email: Option<String>,
|
||||||
|
pub correspondence_user_id: Option<String>,
|
||||||
|
pub image: Option<String>,
|
||||||
|
pub instance_id: Option<Snowflake>,
|
||||||
|
pub auto_create_bot_users: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GeneralConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
instance_name: String::from("Spacebar Instance"),
|
||||||
|
instance_description: Some(String::from(
|
||||||
|
"This is a Spacebar instance made in the pre-release days",
|
||||||
|
)),
|
||||||
|
front_page: None,
|
||||||
|
tos_page: None,
|
||||||
|
correspondence_email: None,
|
||||||
|
correspondence_user_id: None,
|
||||||
|
image: None,
|
||||||
|
instance_id: Some(Snowflake::generate()),
|
||||||
|
auto_create_bot_users: Some(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum GifProvider {
|
||||||
|
#[default]
|
||||||
|
Tenor,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct GifConfiguration {
|
||||||
|
pub enabled: bool,
|
||||||
|
pub provider: GifProvider,
|
||||||
|
pub api_key: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GifConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
enabled: true,
|
||||||
|
provider: GifProvider::Tenor,
|
||||||
|
api_key: Some(String::from("LIVDSRZULELA")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config::types::subconfigs::guild::{
|
||||||
|
autojoin::AutoJoinConfiguration, discovery::DiscoverConfiguration,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
pub enum GuildFeatures {
|
||||||
|
ActivitiesAlpha,
|
||||||
|
ActivitiesEmployee,
|
||||||
|
ActivitiesInternalDev,
|
||||||
|
AnimatedBanner,
|
||||||
|
AnimatedIcon,
|
||||||
|
ApplicationCommandPermissionsV2,
|
||||||
|
AutoModeration,
|
||||||
|
AutoModTriggerKeywordFilter,
|
||||||
|
AutoModTriggerMLSpamFilter,
|
||||||
|
AutoModTriggerSpamLinkFilter,
|
||||||
|
AutoModTriggerUserProfile,
|
||||||
|
Banner,
|
||||||
|
BFG,
|
||||||
|
BoostingTiersExperimentMediumGuild,
|
||||||
|
BoostingTiersExperimentSmallGuild,
|
||||||
|
BotDeveloperEarlyAccess,
|
||||||
|
BurstReactions,
|
||||||
|
CommunityCanary,
|
||||||
|
CommunityExpLargeGated,
|
||||||
|
CommunityExpLargeUngated,
|
||||||
|
CommunityExpMedium,
|
||||||
|
ChannelEmojisGenerated,
|
||||||
|
ChannelHighlights,
|
||||||
|
ChannelHighlightsDisabled,
|
||||||
|
ClydeEnabled,
|
||||||
|
ClydeExperimentEnabled,
|
||||||
|
ClydeDisabled,
|
||||||
|
Community,
|
||||||
|
CreatorAcceptedNewTerms,
|
||||||
|
CreatorMonetizable,
|
||||||
|
CreatorMonetizableDisabled,
|
||||||
|
CreatorMonetizablePendingNewOwnerOnboarding,
|
||||||
|
CreatorMonetizableProvisional,
|
||||||
|
CreatorMonetizableRestricted,
|
||||||
|
CreatorMonetizableWhiteglove,
|
||||||
|
CreatorMonetizableApplicationAllowlist,
|
||||||
|
CreateStorePage,
|
||||||
|
DeveloperSupportServer,
|
||||||
|
DiscoverableDisabled,
|
||||||
|
Discoverable,
|
||||||
|
EnabledDiscoverableBefore,
|
||||||
|
ExposedToActivitiesWTPExperiment,
|
||||||
|
GuestsEnabled,
|
||||||
|
GuildAutomodDefaultList,
|
||||||
|
GuildCommunicationDisabledGuilds,
|
||||||
|
GuildHomeDeprecationOverride,
|
||||||
|
GuildHomeOverride,
|
||||||
|
GuildHomeTest,
|
||||||
|
GuildMemberVerificationExperiment,
|
||||||
|
GuildOnboarding,
|
||||||
|
GuildOnboardingAdminOnly,
|
||||||
|
GuildOnboardingEverEnabled,
|
||||||
|
GuildOnboardingHasPrompts,
|
||||||
|
GuildRoleSubscription,
|
||||||
|
GuildRoleSubscriptionPurchaseFeedbackLoop,
|
||||||
|
GuildRoleSubscriptionTrials,
|
||||||
|
GuildServerGuide,
|
||||||
|
GuildWebPageVanityURL,
|
||||||
|
HadEarlyActivitiesAccess,
|
||||||
|
HasDirectoryEntry,
|
||||||
|
HideFromExperimentUI,
|
||||||
|
Hub,
|
||||||
|
IncreasedThreadLimit,
|
||||||
|
InternalEmployeeOnly,
|
||||||
|
InviteSplash,
|
||||||
|
InvitesDisabled,
|
||||||
|
LinkedToHub,
|
||||||
|
MarketplacesConnectionRoles,
|
||||||
|
MemberProfiles,
|
||||||
|
MemberVerificationGateEnabled,
|
||||||
|
MemberVerificationManualApproval,
|
||||||
|
MobileWebRoleSubscriptionPurchasePage,
|
||||||
|
MonetizationEnabled,
|
||||||
|
MoreEmoji,
|
||||||
|
MoreStickers,
|
||||||
|
News,
|
||||||
|
NewThreadPermissions,
|
||||||
|
Partnered,
|
||||||
|
PremiumTier3Override,
|
||||||
|
PreviewEnabled,
|
||||||
|
RaidAlertsDisabled,
|
||||||
|
RelayEnabled,
|
||||||
|
RestrictSpamRiskGuild,
|
||||||
|
RoleIcons,
|
||||||
|
RoleSubscriptionsAvailableForPurchase,
|
||||||
|
RoleSubscriptionsEnabled,
|
||||||
|
RoleSubscriptionsEnabledForPurchase,
|
||||||
|
Shard,
|
||||||
|
SharedCanvasFriendsAndFamilyTest,
|
||||||
|
Soundboard,
|
||||||
|
SummariesEnabled,
|
||||||
|
SummariesEnabledGA,
|
||||||
|
SummariesDisabledByUser,
|
||||||
|
SummariesEnabledByUser,
|
||||||
|
TextInStageEnabled,
|
||||||
|
TextInVoiceEnabled,
|
||||||
|
ThreadsEnabledTesting,
|
||||||
|
ThreadsEnabled,
|
||||||
|
ThreadDefaultAutoArchiveDuration,
|
||||||
|
ThreadsOnlyChannel,
|
||||||
|
TicketedEventsEnabled,
|
||||||
|
TicketingEnabled,
|
||||||
|
VanityUrls,
|
||||||
|
Verified,
|
||||||
|
VIPRegions,
|
||||||
|
VoiceChannelEffects,
|
||||||
|
WelcomeScreenEnabled,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct GuildConfiguration {
|
||||||
|
pub discovery: DiscoverConfiguration,
|
||||||
|
pub auto_join: AutoJoinConfiguration,
|
||||||
|
#[serde(default)]
|
||||||
|
pub default_features: Vec<GuildFeatures>,
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config::types::subconfigs::kafka::KafkaBroker;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct KafkaConfiguration {
|
||||||
|
#[serde(default)]
|
||||||
|
pub brokers: Option<Vec<KafkaBroker>>,
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config::types::subconfigs::limits::{
|
||||||
|
channel::ChannelLimits, global::GlobalRateLimits, guild::GuildLimits, message::MessageLimits,
|
||||||
|
rates::RateLimits, user::UserLimits,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct LimitsConfiguration {
|
||||||
|
pub user: UserLimits,
|
||||||
|
pub guild: GuildLimits,
|
||||||
|
pub message: MessageLimits,
|
||||||
|
pub channel: ChannelLimits,
|
||||||
|
pub rate: RateLimits,
|
||||||
|
pub absolute_rate: GlobalRateLimits,
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct LoginConfiguration {
|
||||||
|
pub require_captcha: bool,
|
||||||
|
pub require_verification: bool,
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct MetricsConfiguration {
|
||||||
|
pub timeout: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for MetricsConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { timeout: 30000 }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
pub mod api_configuration;
|
||||||
|
pub mod cdn_configuration;
|
||||||
|
pub mod defaults_configuration;
|
||||||
|
pub mod email_configuration;
|
||||||
|
pub mod endpoint_configuration;
|
||||||
|
pub mod external_tokens_configuration;
|
||||||
|
pub mod general_configuration;
|
||||||
|
pub mod gif_configuration;
|
||||||
|
pub mod guild_configuration;
|
||||||
|
pub mod kafka_configuration;
|
||||||
|
pub mod limit_configuration;
|
||||||
|
pub mod login_configuration;
|
||||||
|
pub mod metrics_configuration;
|
||||||
|
pub mod password_reset_configuration;
|
||||||
|
pub mod rabbit_mq_configuration;
|
||||||
|
pub mod region_configuration;
|
||||||
|
pub mod register_configuration;
|
||||||
|
pub mod security_configuration;
|
||||||
|
pub mod sentry_configuration;
|
||||||
|
pub mod subconfigs;
|
||||||
|
pub mod template_configuration;
|
|
@ -0,0 +1,7 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct PasswordResetConfiguration {
|
||||||
|
pub require_captcha: bool,
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RabbitMQConfiguration {
|
||||||
|
pub host: Option<String>,
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config::types::subconfigs::region::Region;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RegionConfiguration {
|
||||||
|
pub default: String,
|
||||||
|
pub use_default_as_optimal: bool,
|
||||||
|
pub available: Vec<Region>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for RegionConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
default: String::from("spacebar"),
|
||||||
|
use_default_as_optimal: true,
|
||||||
|
available: vec![Region {
|
||||||
|
id: String::from("spacebar"),
|
||||||
|
name: String::from("spacebar"),
|
||||||
|
endpoint: String::from("127.0.0.1:3004"),
|
||||||
|
location: None,
|
||||||
|
vip: false,
|
||||||
|
custom: false,
|
||||||
|
deprecated: false,
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config::types::subconfigs::register::{
|
||||||
|
DateOfBirthConfiguration, PasswordConfiguration, RegistrationEmailConfiguration,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RegisterConfiguration {
|
||||||
|
pub email: RegistrationEmailConfiguration,
|
||||||
|
pub date_of_birth: DateOfBirthConfiguration,
|
||||||
|
pub password: PasswordConfiguration,
|
||||||
|
pub disabled: bool,
|
||||||
|
pub require_captcha: bool,
|
||||||
|
pub require_invite: bool,
|
||||||
|
pub guests_require_invite: bool,
|
||||||
|
pub allow_new_registration: bool,
|
||||||
|
pub allow_multiple_accounts: bool,
|
||||||
|
pub block_proxies: bool,
|
||||||
|
pub incrementing_discriminators: bool,
|
||||||
|
pub default_rights: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for RegisterConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
email: RegistrationEmailConfiguration::default(),
|
||||||
|
date_of_birth: DateOfBirthConfiguration::default(),
|
||||||
|
password: PasswordConfiguration::default(),
|
||||||
|
disabled: false,
|
||||||
|
require_captcha: true,
|
||||||
|
require_invite: false,
|
||||||
|
guests_require_invite: true,
|
||||||
|
allow_new_registration: true,
|
||||||
|
allow_multiple_accounts: true,
|
||||||
|
block_proxies: true,
|
||||||
|
incrementing_discriminators: false,
|
||||||
|
default_rights: String::from("875069521787904"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
use base64::Engine;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config::types::subconfigs::security::{CaptchaConfiguration, TwoFactorConfiguration};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SecurityConfiguration {
|
||||||
|
pub captcha: CaptchaConfiguration,
|
||||||
|
pub two_factor: TwoFactorConfiguration,
|
||||||
|
pub auto_update: bool,
|
||||||
|
pub request_signature: String,
|
||||||
|
pub jwt_secret: String,
|
||||||
|
pub forwarded_for: Option<String>,
|
||||||
|
pub ipdata_api_key: Option<String>,
|
||||||
|
pub mfa_backup_code_count: u8,
|
||||||
|
pub stats_world_readable: bool,
|
||||||
|
pub default_registration_token_expiration: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SecurityConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
let mut req_sig: [u8; 32] = [0; 32];
|
||||||
|
let _ = openssl::rand::rand_bytes(&mut req_sig);
|
||||||
|
let mut jwt_secret: [u8; 256] = [0; 256];
|
||||||
|
let _ = openssl::rand::rand_bytes(&mut jwt_secret);
|
||||||
|
Self {
|
||||||
|
captcha: Default::default(),
|
||||||
|
two_factor: Default::default(),
|
||||||
|
auto_update: true,
|
||||||
|
request_signature: base64::engine::general_purpose::STANDARD.encode(req_sig),
|
||||||
|
jwt_secret: base64::engine::general_purpose::STANDARD.encode(jwt_secret),
|
||||||
|
forwarded_for: None,
|
||||||
|
ipdata_api_key: Some(String::from(
|
||||||
|
"eca677b284b3bac29eb72f5e496aa9047f26543605efe99ff2ce35c9",
|
||||||
|
)),
|
||||||
|
mfa_backup_code_count: 10,
|
||||||
|
stats_world_readable: true,
|
||||||
|
default_registration_token_expiration: 1000 * 60 * 60 * 24 * 7,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
use std::ffi::OsString;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SentryConfiguration {
|
||||||
|
pub enabled: bool,
|
||||||
|
pub endpoint: String,
|
||||||
|
pub trace_sample_rate: f64,
|
||||||
|
pub environment: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SentryConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
enabled: false,
|
||||||
|
endpoint: String::from(
|
||||||
|
"https://241c6fb08adb469da1bb82522b25c99f@sentry.quartzinc.space/3",
|
||||||
|
),
|
||||||
|
trace_sample_rate: 1.0,
|
||||||
|
environment: hostname::get()
|
||||||
|
.unwrap_or_else(|_| OsString::new())
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ClientReleaseConfiguration {
|
||||||
|
pub use_local_release: bool,
|
||||||
|
pub upstream_version: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ClientReleaseConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
use_local_release: true,
|
||||||
|
upstream_version: String::from("0.0.264"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct GuildDefaults {
|
||||||
|
pub max_presences: u64,
|
||||||
|
pub max_video_channel_users: u16,
|
||||||
|
pub afk_timeout: u16,
|
||||||
|
pub default_message_notifications: u8,
|
||||||
|
pub explicit_content_filter: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GuildDefaults {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
max_presences: 250_000,
|
||||||
|
max_video_channel_users: 200,
|
||||||
|
afk_timeout: 300,
|
||||||
|
default_message_notifications: 1,
|
||||||
|
explicit_content_filter: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod guild;
|
||||||
|
pub mod user;
|
|
@ -0,0 +1,19 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct UserDefaults {
|
||||||
|
pub premium: bool,
|
||||||
|
pub premium_type: u8,
|
||||||
|
pub verified: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for UserDefaults {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
premium: true,
|
||||||
|
premium_type: 2,
|
||||||
|
verified: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct MailGunConfiguration {
|
||||||
|
pub api_key: Option<String>,
|
||||||
|
pub domain: Option<String>,
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct MailJetConfiguration {
|
||||||
|
pub api_key: Option<String>,
|
||||||
|
pub api_secret: Option<String>,
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
pub mod mailgun;
|
||||||
|
pub mod mailjet;
|
||||||
|
pub mod sendgrid;
|
||||||
|
pub mod smtp;
|
|
@ -0,0 +1,7 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SendGridConfiguration {
|
||||||
|
pub api_key: Option<String>,
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SMTPConfiguration {
|
||||||
|
pub host: Option<String>,
|
||||||
|
pub port: Option<u16>,
|
||||||
|
pub secure: bool,
|
||||||
|
pub username: Option<String>,
|
||||||
|
pub password: Option<String>,
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::utils::Snowflake;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct AutoJoinConfiguration {
|
||||||
|
pub enabled: bool,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub guilds: Option<Vec<Snowflake>>,
|
||||||
|
pub can_leave: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for AutoJoinConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
enabled: true,
|
||||||
|
guilds: None,
|
||||||
|
can_leave: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct DiscoverConfiguration {
|
||||||
|
pub show_all_guilds: bool,
|
||||||
|
pub use_recommendation: bool,
|
||||||
|
pub offset: u16,
|
||||||
|
pub limit: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DiscoverConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
show_all_guilds: false,
|
||||||
|
use_recommendation: false,
|
||||||
|
offset: 0,
|
||||||
|
limit: 24,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod autojoin;
|
||||||
|
pub mod discovery;
|
|
@ -0,0 +1,7 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct KafkaBroker {
|
||||||
|
pub ip: String,
|
||||||
|
pub port: u16,
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ChannelLimits {
|
||||||
|
pub max_pins: u16,
|
||||||
|
pub max_topic: u16,
|
||||||
|
pub max_webhooks: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ChannelLimits {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
max_pins: 500,
|
||||||
|
max_topic: 1024,
|
||||||
|
max_webhooks: 100,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct GlobalRateLimit {
|
||||||
|
pub limit: u16,
|
||||||
|
pub window: u64,
|
||||||
|
pub enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GlobalRateLimit {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
limit: 100,
|
||||||
|
window: 60 * 60 * 1000,
|
||||||
|
enabled: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct GlobalRateLimits {
|
||||||
|
pub register: GlobalRateLimit,
|
||||||
|
pub send_message: GlobalRateLimit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GlobalRateLimits {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
register: GlobalRateLimit {
|
||||||
|
limit: 25,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
send_message: GlobalRateLimit {
|
||||||
|
limit: 200,
|
||||||
|
window: 60 * 1000,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct GuildLimits {
|
||||||
|
pub max_roles: u16,
|
||||||
|
pub max_emojis: u16,
|
||||||
|
pub max_members: u64,
|
||||||
|
pub max_channels: u32,
|
||||||
|
pub max_channels_in_category: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GuildLimits {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
max_roles: 1000,
|
||||||
|
max_emojis: 20_000,
|
||||||
|
max_members: 25_000_000,
|
||||||
|
max_channels: 65_535,
|
||||||
|
max_channels_in_category: 65_535,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct MessageLimits {
|
||||||
|
pub max_characters: u32,
|
||||||
|
#[serde(default)]
|
||||||
|
pub max_tts_characters: u32,
|
||||||
|
pub max_reactions: u32,
|
||||||
|
pub max_attachment_size: u64,
|
||||||
|
pub max_bulk_delete: u32,
|
||||||
|
pub max_embed_download_size: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for MessageLimits {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
max_characters: 1048576,
|
||||||
|
max_tts_characters: 160,
|
||||||
|
max_reactions: 2048,
|
||||||
|
max_attachment_size: 1024 * 1024 * 1024,
|
||||||
|
max_bulk_delete: 1000,
|
||||||
|
max_embed_download_size: 1024 * 1024 * 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
pub mod channel;
|
||||||
|
pub mod global;
|
||||||
|
pub mod guild;
|
||||||
|
pub mod message;
|
||||||
|
pub mod ratelimits;
|
||||||
|
pub mod rates;
|
||||||
|
pub mod user;
|
|
@ -0,0 +1,28 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config::types::subconfigs::limits::ratelimits::RateLimitOptions;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct AuthRateLimit {
|
||||||
|
pub login: RateLimitOptions,
|
||||||
|
pub register: RateLimitOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for AuthRateLimit {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
login: RateLimitOptions {
|
||||||
|
bot: None,
|
||||||
|
count: 5,
|
||||||
|
window: 60,
|
||||||
|
only_ip: false,
|
||||||
|
},
|
||||||
|
register: RateLimitOptions {
|
||||||
|
bot: None,
|
||||||
|
count: 2,
|
||||||
|
window: 60 * 60 * 12,
|
||||||
|
only_ip: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub mod auth;
|
||||||
|
pub mod route;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RateLimitOptions {
|
||||||
|
pub bot: Option<u64>,
|
||||||
|
pub count: u64,
|
||||||
|
pub window: u64,
|
||||||
|
#[serde(default)]
|
||||||
|
pub only_ip: bool,
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config::types::subconfigs::limits::ratelimits::{auth::AuthRateLimit, RateLimitOptions};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct RouteRateLimit {
|
||||||
|
pub guild: RateLimitOptions,
|
||||||
|
pub webhook: RateLimitOptions,
|
||||||
|
pub channel: RateLimitOptions,
|
||||||
|
pub auth: AuthRateLimit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for RouteRateLimit {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
guild: RateLimitOptions {
|
||||||
|
bot: None,
|
||||||
|
count: 5,
|
||||||
|
window: 5,
|
||||||
|
only_ip: false,
|
||||||
|
},
|
||||||
|
webhook: RateLimitOptions {
|
||||||
|
bot: None,
|
||||||
|
count: 10,
|
||||||
|
window: 5,
|
||||||
|
only_ip: false,
|
||||||
|
},
|
||||||
|
channel: RateLimitOptions {
|
||||||
|
bot: None,
|
||||||
|
count: 10,
|
||||||
|
window: 5,
|
||||||
|
only_ip: false,
|
||||||
|
},
|
||||||
|
auth: AuthRateLimit::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config::types::subconfigs::limits::ratelimits::{
|
||||||
|
route::RouteRateLimit, RateLimitOptions,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct RateLimits {
|
||||||
|
pub enabled: bool,
|
||||||
|
pub ip: RateLimitOptions,
|
||||||
|
pub global: RateLimitOptions,
|
||||||
|
pub error: RateLimitOptions,
|
||||||
|
pub routes: RouteRateLimit,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for RateLimits {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
enabled: false,
|
||||||
|
ip: RateLimitOptions {
|
||||||
|
bot: None,
|
||||||
|
count: 500,
|
||||||
|
window: 5,
|
||||||
|
only_ip: false,
|
||||||
|
},
|
||||||
|
global: RateLimitOptions {
|
||||||
|
bot: None,
|
||||||
|
count: 250,
|
||||||
|
window: 5,
|
||||||
|
only_ip: false,
|
||||||
|
},
|
||||||
|
error: RateLimitOptions {
|
||||||
|
bot: None,
|
||||||
|
count: 10,
|
||||||
|
window: 5,
|
||||||
|
only_ip: false,
|
||||||
|
},
|
||||||
|
routes: RouteRateLimit::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct UserLimits {
|
||||||
|
pub max_guilds: u64,
|
||||||
|
pub max_username: u16,
|
||||||
|
pub max_friends: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for UserLimits {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
max_guilds: 1048576,
|
||||||
|
max_username: 32,
|
||||||
|
max_friends: 5000,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
pub mod client;
|
||||||
|
pub mod defaults;
|
||||||
|
pub mod email;
|
||||||
|
pub mod guild;
|
||||||
|
pub mod kafka;
|
||||||
|
pub mod limits;
|
||||||
|
pub mod region;
|
||||||
|
pub mod register;
|
||||||
|
pub mod security;
|
|
@ -0,0 +1,21 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct LatLong {
|
||||||
|
pub latitude: f64,
|
||||||
|
pub longitude: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Region {
|
||||||
|
pub id: String,
|
||||||
|
pub name: String,
|
||||||
|
pub endpoint: String,
|
||||||
|
pub location: Option<LatLong>,
|
||||||
|
pub vip: bool,
|
||||||
|
pub custom: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub deprecated: bool,
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct DateOfBirthConfiguration {
|
||||||
|
pub required: bool,
|
||||||
|
pub minimum: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DateOfBirthConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
required: true,
|
||||||
|
minimum: 13,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct RegistrationEmailConfiguration {
|
||||||
|
pub required: bool,
|
||||||
|
pub allowlist: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub blacklist: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub domains: Vec<String>,
|
||||||
|
}
|
||||||
|
impl Default for RegistrationEmailConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
required: false,
|
||||||
|
allowlist: false,
|
||||||
|
blacklist: true,
|
||||||
|
domains: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
mod date_of_birth;
|
||||||
|
mod email;
|
||||||
|
mod password;
|
||||||
|
|
||||||
|
pub use date_of_birth::DateOfBirthConfiguration;
|
||||||
|
pub use email::RegistrationEmailConfiguration;
|
||||||
|
pub use password::PasswordConfiguration;
|
|
@ -0,0 +1,23 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct PasswordConfiguration {
|
||||||
|
pub required: bool,
|
||||||
|
pub min_length: u8,
|
||||||
|
pub min_numbers: u8,
|
||||||
|
pub min_upper_case: u8,
|
||||||
|
pub min_symbols: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PasswordConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
required: false,
|
||||||
|
min_length: 8,
|
||||||
|
min_numbers: 2,
|
||||||
|
min_upper_case: 2,
|
||||||
|
min_symbols: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum CaptchaService {
|
||||||
|
Recaptcha,
|
||||||
|
HCaptcha,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct CaptchaConfiguration {
|
||||||
|
pub enabled: bool,
|
||||||
|
pub service: CaptchaService,
|
||||||
|
pub sitekey: Option<String>,
|
||||||
|
pub secret: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for CaptchaConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
enabled: false,
|
||||||
|
service: CaptchaService::HCaptcha,
|
||||||
|
sitekey: None,
|
||||||
|
secret: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
mod captcha;
|
||||||
|
mod twofactor;
|
||||||
|
|
||||||
|
pub use captcha::{CaptchaConfiguration, CaptchaService};
|
||||||
|
pub use twofactor::TwoFactorConfiguration;
|
|
@ -0,0 +1,15 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct TwoFactorConfiguration {
|
||||||
|
pub generate_backup_codes: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for TwoFactorConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
generate_backup_codes: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct TemplateConfiguration {
|
||||||
|
pub enabled: bool,
|
||||||
|
pub allow_template_creation: bool,
|
||||||
|
pub allow_discord_templates: bool,
|
||||||
|
pub allow_raws: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for TemplateConfiguration {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
enabled: true,
|
||||||
|
allow_template_creation: true,
|
||||||
|
allow_discord_templates: true,
|
||||||
|
allow_raws: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
|
||||||
|
|
||||||
|
use crate::utils::Snowflake;
|
||||||
|
use bitflags::{bitflags, Flags};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::Value;
|
||||||
|
#[cfg(feature = "sqlx")]
|
||||||
|
use sqlx::FromRow;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "sqlx", derive(FromRow))]
|
||||||
|
pub struct Application {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub name: String,
|
||||||
|
pub icon: Option<String>,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub summary: Option<String>,
|
||||||
|
#[cfg(feature = "sqlx")]
|
||||||
|
pub r#type: Option<sqlx::types::Json<Value>>,
|
||||||
|
#[cfg(not(feature = "sqlx"))]
|
||||||
|
pub r#type: Option<Value>,
|
||||||
|
pub hook: bool,
|
||||||
|
pub bot_public: bool,
|
||||||
|
pub bot_require_code_grant: bool,
|
||||||
|
pub verify_key: String,
|
||||||
|
pub owner_id: Snowflake,
|
||||||
|
pub flags: u64,
|
||||||
|
#[cfg(feature = "sqlx")]
|
||||||
|
pub redirect_uris: Option<sqlx::types::Json<Vec<String>>>,
|
||||||
|
#[cfg(not(feature = "sqlx"))]
|
||||||
|
pub redirect_uris: Option<Vec<String>>,
|
||||||
|
pub rpc_application_state: i64,
|
||||||
|
pub store_application_state: i64,
|
||||||
|
pub verification_state: i64,
|
||||||
|
pub interactions_endpoint_url: Option<String>,
|
||||||
|
pub integration_public: bool,
|
||||||
|
pub integration_require_code_grant: bool,
|
||||||
|
pub discoverability_state: i64,
|
||||||
|
pub discovery_eligibility_flags: i64,
|
||||||
|
pub bot_user_id: Snowflake,
|
||||||
|
#[cfg(feature = "sqlx")]
|
||||||
|
pub tags: Option<sqlx::types::Json<Vec<String>>>,
|
||||||
|
#[cfg(not(feature = "sqlx"))]
|
||||||
|
pub tags: Option<Vec<String>>,
|
||||||
|
pub cover_image: Option<String>,
|
||||||
|
#[cfg(feature = "sqlx")]
|
||||||
|
pub install_params: Option<sqlx::types::Json<InstallParams>>,
|
||||||
|
#[cfg(not(feature = "sqlx"))]
|
||||||
|
pub install_params: Option<InstallParams>,
|
||||||
|
pub terms_of_service_url: Option<String>,
|
||||||
|
pub privacy_policy_url: Option<String>,
|
||||||
|
pub team_id: Option<Snowflake>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Application {
|
||||||
|
pub fn flags(&self) -> ApplicationFlags {
|
||||||
|
ApplicationFlags::from_bits(self.flags.to_owned()).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct InstallParams {
|
||||||
|
pub scopes: Vec<String>,
|
||||||
|
pub permissions: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct ApplicationFlags: u64 {
|
||||||
|
const APPLICATION_AUTO_MODERATION_RULE_CREATE_BADGE = 1 << 6;
|
||||||
|
const GATEWAY_PRESENCE = 1 << 12;
|
||||||
|
const GATEWAY_PRESENCE_LIMITED = 1 << 13;
|
||||||
|
const GATEWAY_GUILD_MEMBERS = 1 << 14;
|
||||||
|
const GATEWAY_GUILD_MEMBERS_LIMITED = 1 << 15;
|
||||||
|
const VERIFICATION_PENDING_GUILD_LIMIT = 1 << 16;
|
||||||
|
const EMBEDDED = 1 << 17;
|
||||||
|
const GATEWAY_MESSAGE_CONTENT = 1 << 18;
|
||||||
|
const GATEWAY_MESSAGE_CONTENT_LIMITED = 1 << 19;
|
||||||
|
const APPLICATION_COMMAND_BADGE = 1 << 23;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct ApplicationCommand {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub application_id: Snowflake,
|
||||||
|
pub name: String,
|
||||||
|
pub description: String,
|
||||||
|
pub options: Vec<ApplicationCommandOption>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct ApplicationCommandOption {
|
||||||
|
pub r#type: ApplicationCommandOptionType,
|
||||||
|
pub name: String,
|
||||||
|
pub description: String,
|
||||||
|
pub required: bool,
|
||||||
|
pub choices: Vec<ApplicationCommandOptionChoice>,
|
||||||
|
pub options: Vec<ApplicationCommandOption>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct ApplicationCommandOptionChoice {
|
||||||
|
pub name: String,
|
||||||
|
pub value: Value,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum ApplicationCommandOptionType {
|
||||||
|
#[serde(rename = "SUB_COMMAND")]
|
||||||
|
SubCommand = 1,
|
||||||
|
#[serde(rename = "SUB_COMMAND_GROUP")]
|
||||||
|
SubCommandGroup = 2,
|
||||||
|
#[serde(rename = "STRING")]
|
||||||
|
String = 3,
|
||||||
|
#[serde(rename = "INTEGER")]
|
||||||
|
Integer = 4,
|
||||||
|
#[serde(rename = "BOOLEAN")]
|
||||||
|
Boolean = 5,
|
||||||
|
#[serde(rename = "USER")]
|
||||||
|
User = 6,
|
||||||
|
#[serde(rename = "CHANNEL")]
|
||||||
|
Channel = 7,
|
||||||
|
#[serde(rename = "ROLE")]
|
||||||
|
Role = 8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct ApplicationCommandInteractionData {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub name: String,
|
||||||
|
pub options: Vec<ApplicationCommandInteractionDataOption>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct ApplicationCommandInteractionDataOption {
|
||||||
|
pub name: String,
|
||||||
|
pub value: Value,
|
||||||
|
pub options: Vec<ApplicationCommandInteractionDataOption>,
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::utils::Snowflake;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Attachment {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub filename: String,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub content_type: Option<String>,
|
||||||
|
pub size: u64,
|
||||||
|
pub url: String,
|
||||||
|
pub proxy_url: String,
|
||||||
|
pub height: Option<u64>,
|
||||||
|
pub width: Option<u64>,
|
||||||
|
pub message_id: Snowflake,
|
||||||
|
pub ephemeral: Option<bool>,
|
||||||
|
pub duration_secs: Option<f32>,
|
||||||
|
pub waveform: Option<String>,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
pub content: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
|
||||||
|
pub struct PartialDiscordFileAttachment {
|
||||||
|
pub id: Option<i16>,
|
||||||
|
pub filename: String,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub content_type: Option<String>,
|
||||||
|
pub size: Option<i64>,
|
||||||
|
pub url: Option<String>,
|
||||||
|
pub proxy_url: Option<String>,
|
||||||
|
pub height: Option<i32>,
|
||||||
|
pub width: Option<i32>,
|
||||||
|
pub ephemeral: Option<bool>,
|
||||||
|
pub duration_secs: Option<f32>,
|
||||||
|
pub waveform: Option<String>,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
pub content: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialDiscordFileAttachment {
|
||||||
|
/**
|
||||||
|
Moves `self.content` out of `self` and returns it.
|
||||||
|
# Returns
|
||||||
|
Vec<u8>
|
||||||
|
*/
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
entities::{GuildMember, User},
|
||||||
|
utils::Snowflake,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
|
pub struct Channel {
|
||||||
|
pub id: Snowflake,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub channel_type: ChannelType,
|
||||||
|
pub guild_id: Option<String>,
|
||||||
|
pub position: Option<i32>,
|
||||||
|
pub permission_overwrites: Option<Vec<PermissionOverwrite>>,
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub topic: Option<String>,
|
||||||
|
pub nsfw: Option<bool>,
|
||||||
|
pub last_message_id: Option<String>,
|
||||||
|
pub bitrate: Option<i32>,
|
||||||
|
pub user_limit: Option<i32>,
|
||||||
|
pub rate_limit_per_user: Option<i32>,
|
||||||
|
pub recipients: Option<Vec<User>>,
|
||||||
|
pub icon: Option<String>,
|
||||||
|
pub owner_id: Option<String>,
|
||||||
|
pub application_id: Option<String>,
|
||||||
|
pub parent_id: Option<String>,
|
||||||
|
pub last_pin_timestamp: Option<String>,
|
||||||
|
pub rtc_region: Option<String>,
|
||||||
|
pub video_quality_mode: Option<i32>,
|
||||||
|
pub message_count: Option<i32>,
|
||||||
|
pub member_count: Option<i32>,
|
||||||
|
pub thread_metadata: Option<ThreadMetadata>,
|
||||||
|
pub member: Option<ThreadMember>,
|
||||||
|
pub default_auto_archive_duration: Option<i32>,
|
||||||
|
pub permissions: Option<String>,
|
||||||
|
pub flags: Option<i32>,
|
||||||
|
pub total_message_sent: Option<i32>,
|
||||||
|
pub available_tags: Option<Vec<Tag>>,
|
||||||
|
pub applied_tags: Option<Vec<String>>,
|
||||||
|
pub default_reaction_emoji: Option<DefaultReaction>,
|
||||||
|
pub default_thread_rate_limit_per_user: Option<i32>,
|
||||||
|
pub default_sort_order: Option<i32>,
|
||||||
|
pub default_forum_layout: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||||
|
pub struct Tag {
|
||||||
|
pub id: u64,
|
||||||
|
pub name: String,
|
||||||
|
pub moderated: bool,
|
||||||
|
pub emoji_id: Option<u64>,
|
||||||
|
pub emoji_name: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
|
pub struct PermissionOverwrite {
|
||||||
|
pub id: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub overwrite_type: u8,
|
||||||
|
pub allow: String,
|
||||||
|
pub deny: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||||
|
pub struct ThreadMetadata {
|
||||||
|
pub archived: bool,
|
||||||
|
pub auto_archive_duration: i32,
|
||||||
|
pub archive_timestamp: String,
|
||||||
|
pub locked: bool,
|
||||||
|
pub invitable: Option<bool>,
|
||||||
|
pub create_timestamp: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||||
|
pub struct ThreadMember {
|
||||||
|
pub id: Option<u64>,
|
||||||
|
pub user_id: Option<u64>,
|
||||||
|
pub join_timestamp: Option<String>,
|
||||||
|
pub flags: Option<u64>,
|
||||||
|
pub member: Option<GuildMember>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||||
|
pub struct DefaultReaction {
|
||||||
|
pub emoji_id: Option<String>,
|
||||||
|
pub emoji_name: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
#[repr(i32)]
|
||||||
|
pub enum ChannelType {
|
||||||
|
#[default]
|
||||||
|
GuildText = 0,
|
||||||
|
Dm = 1,
|
||||||
|
GuildVoice = 2,
|
||||||
|
GroupDm = 3,
|
||||||
|
GuildCategory = 4,
|
||||||
|
GuildNews = 5,
|
||||||
|
GuildStore = 6,
|
||||||
|
Encrypted = 7,
|
||||||
|
EncryptedThreads = 8,
|
||||||
|
Transactional = 9,
|
||||||
|
GuildNewsThread = 10,
|
||||||
|
GuildPublicThread = 11,
|
||||||
|
GuildPrivateThread = 12,
|
||||||
|
GuildStageVoice = 13,
|
||||||
|
Directory = 14,
|
||||||
|
GuildForum = 15,
|
||||||
|
TicketTracker = 33,
|
||||||
|
Kanban = 34,
|
||||||
|
VoicelessWhiteboard = 35,
|
||||||
|
CustomStart = 64,
|
||||||
|
Unhandled = 255,
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::Value;
|
||||||
|
#[cfg(feature = "sqlx")]
|
||||||
|
use sqlx::FromRow;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "sqlx", derive(FromRow))]
|
||||||
|
pub struct ConfigEntity {
|
||||||
|
pub key: String,
|
||||||
|
pub value: Option<Value>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConfigEntity {
|
||||||
|
pub fn as_string(&self) -> Option<String> {
|
||||||
|
let Some(v) = self.value.as_ref() else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
Some(v.as_str().expect("value is not a string").to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_bool(&self) -> Option<bool> {
|
||||||
|
let Some(v) = self.value.as_ref() else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
Some(v.as_bool().expect("value is not a boolean"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_int(&self) -> Option<i64> {
|
||||||
|
let Some(v) = self.value.as_ref() else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
Some(v.as_i64().expect("value is not a number"))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::entities::User;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
|
||||||
|
pub struct Emoji {
|
||||||
|
pub id: Option<u64>,
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub roles: Option<Vec<u64>>,
|
||||||
|
pub user: Option<User>,
|
||||||
|
pub require_colons: Option<bool>,
|
||||||
|
pub managed: Option<bool>,
|
||||||
|
pub animated: Option<bool>,
|
||||||
|
pub available: Option<bool>,
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
entities::{Channel, Emoji, GuildTemplate, RoleObject, Sticker, User, VoiceState, Webhook},
|
||||||
|
interfaces::WelcomeScreenObject,
|
||||||
|
utils::Snowflake,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// See https://discord.com/developers/docs/resources/guild
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
pub struct Guild {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub name: String,
|
||||||
|
pub icon: Option<String>,
|
||||||
|
pub icon_hash: Option<String>,
|
||||||
|
pub splash: Option<String>,
|
||||||
|
pub discovery_splash: Option<String>,
|
||||||
|
pub owner: Option<User>,
|
||||||
|
pub owner_id: Option<Snowflake>,
|
||||||
|
pub permissions: Option<String>,
|
||||||
|
pub afk_channel_id: Option<Snowflake>,
|
||||||
|
pub afk_timeout: Option<u8>,
|
||||||
|
pub widget_enabled: Option<bool>,
|
||||||
|
pub widget_channel_id: Option<Snowflake>,
|
||||||
|
pub widget_channel: Option<Channel>,
|
||||||
|
pub verification_level: Option<u8>,
|
||||||
|
pub default_message_notifications: Option<u8>,
|
||||||
|
pub explicit_content_filter: Option<u8>,
|
||||||
|
pub roles: Vec<RoleObject>,
|
||||||
|
pub emojis: Vec<Emoji>,
|
||||||
|
pub features: Vec<String>,
|
||||||
|
pub application_id: Option<String>,
|
||||||
|
pub system_channel_id: Option<Snowflake>,
|
||||||
|
pub system_channel_flags: Option<u8>,
|
||||||
|
pub rules_channel_id: Option<String>,
|
||||||
|
pub rules_channel: Option<String>,
|
||||||
|
pub max_presences: Option<u64>,
|
||||||
|
pub max_members: Option<u64>,
|
||||||
|
pub vanity_url_code: Option<String>,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub banner: Option<String>,
|
||||||
|
pub premium_tier: Option<u8>,
|
||||||
|
pub premium_subscription_count: Option<u64>,
|
||||||
|
pub preferred_locale: Option<String>,
|
||||||
|
pub public_updates_channel_id: Option<Snowflake>,
|
||||||
|
pub public_updates_channel: Option<Channel>,
|
||||||
|
pub max_video_channel_users: Option<u8>,
|
||||||
|
pub max_stage_video_channel_users: Option<u8>,
|
||||||
|
pub approximate_member_count: Option<u64>,
|
||||||
|
pub approximate_presence_count: Option<u64>,
|
||||||
|
pub member_count: Option<u64>,
|
||||||
|
pub presence_count: Option<u64>,
|
||||||
|
pub welcome_screen: Option<WelcomeScreenObject>,
|
||||||
|
pub nsfw_level: u8,
|
||||||
|
pub nsfw: bool,
|
||||||
|
pub stickers: Option<Vec<Sticker>>,
|
||||||
|
pub premium_progress_bar_enabled: Option<bool>,
|
||||||
|
pub joined_at: String,
|
||||||
|
pub afk_channel: Option<Channel>,
|
||||||
|
pub bans: Option<Vec<GuildBan>>,
|
||||||
|
pub primary_category_id: Option<Snowflake>,
|
||||||
|
pub large: Option<bool>,
|
||||||
|
pub channels: Option<Vec<Channel>>,
|
||||||
|
pub template_id: Option<Snowflake>,
|
||||||
|
pub template: Option<GuildTemplate>,
|
||||||
|
pub invites: Option<Vec<GuildInvite>>,
|
||||||
|
pub voice_states: Option<Vec<VoiceState>>,
|
||||||
|
pub webhooks: Option<Vec<Webhook>>,
|
||||||
|
pub mfa_level: Option<u8>,
|
||||||
|
pub region: Option<String>,
|
||||||
|
pub unavailable: bool,
|
||||||
|
pub parent: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See https://docs.spacebar.chat/routes/#get-/guilds/-guild_id-/bans/-user-
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
pub struct GuildBan {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub user_id: Snowflake,
|
||||||
|
pub guild_id: Snowflake,
|
||||||
|
pub executor_id: Snowflake,
|
||||||
|
pub reason: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See https://docs.spacebar.chat/routes/#cmp--schemas-invite
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
pub struct GuildInvite {
|
||||||
|
pub code: String,
|
||||||
|
pub temporary: Option<bool>,
|
||||||
|
pub uses: Option<i32>,
|
||||||
|
pub max_uses: Option<i32>,
|
||||||
|
pub max_age: Option<i32>,
|
||||||
|
pub created_at: DateTime<Utc>,
|
||||||
|
pub expires_at: Option<DateTime<Utc>>,
|
||||||
|
pub guild_id: String,
|
||||||
|
pub guild: Option<Guild>,
|
||||||
|
pub channel_id: String,
|
||||||
|
pub channel: Option<Channel>,
|
||||||
|
pub inviter_id: Option<String>,
|
||||||
|
pub inviter: Option<User>,
|
||||||
|
pub target_user_id: Option<String>,
|
||||||
|
pub target_user: Option<String>,
|
||||||
|
pub target_user_type: Option<i32>,
|
||||||
|
pub vanity_url: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||||
|
pub struct UnavailableGuild {
|
||||||
|
id: String,
|
||||||
|
unavailable: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
pub struct GuildCreateResponse {
|
||||||
|
pub id: String,
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::entities::User;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||||
|
pub struct GuildMember {
|
||||||
|
pub user: Option<User>,
|
||||||
|
pub nick: Option<String>,
|
||||||
|
pub avatar: Option<String>,
|
||||||
|
pub roles: Vec<String>,
|
||||||
|
pub joined_at: String,
|
||||||
|
pub premium_since: Option<String>,
|
||||||
|
pub deaf: bool,
|
||||||
|
pub mute: bool,
|
||||||
|
pub flags: i32,
|
||||||
|
pub pending: Option<bool>,
|
||||||
|
pub permissions: Option<String>,
|
||||||
|
pub communication_disabled_until: Option<String>,
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
entities::{Application, User},
|
||||||
|
utils::Snowflake,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Deserialize, Serialize, Clone)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/guild#integration-object-integration-structure
|
||||||
|
pub struct Integration {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub name: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub integration_type: String,
|
||||||
|
pub enabled: bool,
|
||||||
|
pub syncing: Option<bool>,
|
||||||
|
pub role_id: Option<String>,
|
||||||
|
pub enabled_emoticons: Option<bool>,
|
||||||
|
pub expire_behaviour: Option<u8>,
|
||||||
|
pub expire_grace_period: Option<u16>,
|
||||||
|
pub user: Option<User>,
|
||||||
|
pub account: IntegrationAccount,
|
||||||
|
pub synced_at: Option<DateTime<Utc>>,
|
||||||
|
pub subscriber_count: Option<f64>,
|
||||||
|
pub revoked: Option<bool>,
|
||||||
|
pub application: Option<Application>,
|
||||||
|
pub scopes: Option<Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Deserialize, Serialize, Clone)]
|
||||||
|
/// See https://discord.com/developers/docs/resources/guild#integration-account-object-integration-account-structure
|
||||||
|
pub struct IntegrationAccount {
|
||||||
|
pub id: String,
|
||||||
|
pub name: String,
|
||||||
|
}
|
|
@ -0,0 +1,185 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
entities::{
|
||||||
|
Application, Attachment, Channel, Emoji, GuildMember, RoleSubscriptionData, Sticker,
|
||||||
|
StickerItem, User,
|
||||||
|
},
|
||||||
|
utils::Snowflake,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
pub struct Message {
|
||||||
|
id: Snowflake,
|
||||||
|
pub channel_id: Snowflake,
|
||||||
|
author: User,
|
||||||
|
content: String,
|
||||||
|
timestamp: String,
|
||||||
|
edited_timestamp: Option<String>,
|
||||||
|
tts: bool,
|
||||||
|
mention_everyone: bool,
|
||||||
|
mentions: Vec<User>,
|
||||||
|
mention_roles: Vec<String>,
|
||||||
|
mention_channels: Option<Vec<ChannelMention>>,
|
||||||
|
pub attachments: Vec<Attachment>,
|
||||||
|
embeds: Vec<Embed>,
|
||||||
|
reactions: Option<Vec<Reaction>>,
|
||||||
|
nonce: Option<serde_json::Value>,
|
||||||
|
pinned: bool,
|
||||||
|
webhook_id: Option<String>,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
message_type: i32,
|
||||||
|
activity: Option<MessageActivity>,
|
||||||
|
application: Option<Application>,
|
||||||
|
application_id: Option<String>,
|
||||||
|
message_reference: Option<MessageReference>,
|
||||||
|
flags: Option<i32>,
|
||||||
|
referenced_message: Option<Box<Message>>,
|
||||||
|
interaction: Option<MessageInteraction>,
|
||||||
|
thread: Option<Channel>,
|
||||||
|
components: Option<Vec<Component>>,
|
||||||
|
sticker_items: Option<Vec<StickerItem>>,
|
||||||
|
stickers: Option<Vec<Sticker>>,
|
||||||
|
position: Option<i32>,
|
||||||
|
role_subscription_data: Option<RoleSubscriptionData>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct MessageReference {
|
||||||
|
pub message_id: Snowflake,
|
||||||
|
pub channel_id: Snowflake,
|
||||||
|
pub guild_id: Option<Snowflake>,
|
||||||
|
pub fail_if_not_exists: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
pub struct MessageInteraction {
|
||||||
|
pub id: Snowflake,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub interaction_type: u8,
|
||||||
|
pub name: String,
|
||||||
|
pub user: User,
|
||||||
|
pub member: Option<GuildMember>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct AllowedMention {
|
||||||
|
parse: Vec<AllowedMentionType>,
|
||||||
|
roles: Vec<Snowflake>,
|
||||||
|
users: Vec<Snowflake>,
|
||||||
|
replied_user: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum AllowedMentionType {
|
||||||
|
Roles,
|
||||||
|
Users,
|
||||||
|
Everyone,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct ChannelMention {
|
||||||
|
id: Snowflake,
|
||||||
|
guild_id: Snowflake,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
channel_type: i32,
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Embed {
|
||||||
|
title: Option<String>,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
embed_type: Option<String>,
|
||||||
|
description: Option<String>,
|
||||||
|
url: Option<String>,
|
||||||
|
timestamp: Option<String>,
|
||||||
|
color: Option<i32>,
|
||||||
|
footer: Option<EmbedFooter>,
|
||||||
|
image: Option<EmbedImage>,
|
||||||
|
thumbnail: Option<EmbedThumbnail>,
|
||||||
|
video: Option<EmbedVideo>,
|
||||||
|
provider: Option<EmbedProvider>,
|
||||||
|
author: Option<EmbedAuthor>,
|
||||||
|
fields: Option<Vec<EmbedField>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct EmbedFooter {
|
||||||
|
text: String,
|
||||||
|
icon_url: Option<String>,
|
||||||
|
proxy_icon_url: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct EmbedImage {
|
||||||
|
url: String,
|
||||||
|
proxy_url: String,
|
||||||
|
height: Option<i32>,
|
||||||
|
width: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct EmbedThumbnail {
|
||||||
|
url: String,
|
||||||
|
proxy_url: Option<String>,
|
||||||
|
height: Option<i32>,
|
||||||
|
width: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct EmbedVideo {
|
||||||
|
url: Option<String>,
|
||||||
|
proxy_url: Option<String>,
|
||||||
|
height: Option<i32>,
|
||||||
|
width: Option<i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct EmbedProvider {
|
||||||
|
name: Option<String>,
|
||||||
|
url: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct EmbedAuthor {
|
||||||
|
name: String,
|
||||||
|
url: Option<String>,
|
||||||
|
icon_url: Option<String>,
|
||||||
|
proxy_icon_url: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
|
||||||
|
struct EmbedField {
|
||||||
|
name: String,
|
||||||
|
value: String,
|
||||||
|
inline: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Reaction {
|
||||||
|
pub count: i32,
|
||||||
|
pub me: bool,
|
||||||
|
pub emoji: Emoji,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub enum Component {
|
||||||
|
ActionRow = 1,
|
||||||
|
Button = 2,
|
||||||
|
StringSelect = 3,
|
||||||
|
TextInput = 4,
|
||||||
|
UserSelect = 5,
|
||||||
|
RoleSelect = 6,
|
||||||
|
MentionableSelect = 7,
|
||||||
|
ChannelSelect = 8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct MessageActivity {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub activity_type: i64,
|
||||||
|
pub party_id: Option<String>,
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
mod application;
|
||||||
|
mod attachment;
|
||||||
|
mod channel;
|
||||||
|
mod config;
|
||||||
|
mod emoji;
|
||||||
|
mod guild;
|
||||||
|
mod guild_member;
|
||||||
|
mod integration;
|
||||||
|
mod message;
|
||||||
|
mod role;
|
||||||
|
mod security_key;
|
||||||
|
mod sticker;
|
||||||
|
mod team;
|
||||||
|
mod template;
|
||||||
|
mod user;
|
||||||
|
mod user_settings;
|
||||||
|
mod voice_state;
|
||||||
|
mod webhook;
|
||||||
|
|
||||||
|
pub use application::*;
|
||||||
|
pub use attachment::*;
|
||||||
|
pub use channel::*;
|
||||||
|
pub use config::*;
|
||||||
|
pub use emoji::*;
|
||||||
|
pub use guild::*;
|
||||||
|
pub use guild_member::*;
|
||||||
|
pub use integration::*;
|
||||||
|
pub use message::*;
|
||||||
|
pub use role::*;
|
||||||
|
pub use security_key::*;
|
||||||
|
pub use sticker::*;
|
||||||
|
pub use team::*;
|
||||||
|
pub use template::*;
|
||||||
|
pub use user::*;
|
||||||
|
pub use user_settings::*;
|
||||||
|
pub use voice_state::*;
|
||||||
|
pub use webhook::*;
|
|
@ -0,0 +1,28 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::utils::Snowflake;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/permissions#role-object
|
||||||
|
pub struct RoleObject {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub name: String,
|
||||||
|
pub color: f64,
|
||||||
|
pub hoist: bool,
|
||||||
|
pub icon: Option<String>,
|
||||||
|
pub unicode_emoji: Option<String>,
|
||||||
|
pub position: u16,
|
||||||
|
pub permissions: String,
|
||||||
|
pub managed: bool,
|
||||||
|
pub mentionable: bool,
|
||||||
|
// to:do add role tags https://discord.com/developers/docs/topics/permissions#role-object-role-tags-structure
|
||||||
|
//pub tags: Option<RoleTags>
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct RoleSubscriptionData {
|
||||||
|
pub role_subscription_listing_id: Snowflake,
|
||||||
|
pub tier_name: String,
|
||||||
|
pub total_months_subscribed: u32,
|
||||||
|
pub is_renewal: bool,
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::utils::Snowflake;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct SecurityKey {
|
||||||
|
pub id: String,
|
||||||
|
pub user_id: String,
|
||||||
|
pub key_id: String,
|
||||||
|
pub public_key: String,
|
||||||
|
pub counter: u64,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SecurityKey {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
id: Snowflake::generate().to_string(),
|
||||||
|
user_id: String::new(),
|
||||||
|
key_id: String::new(),
|
||||||
|
public_key: String::new(),
|
||||||
|
counter: 0,
|
||||||
|
name: String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{entities::User, utils::Snowflake};
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct Sticker {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub pack_id: Option<Snowflake>,
|
||||||
|
pub name: String,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub tags: String,
|
||||||
|
pub asset: Option<String>,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub sticker_type: u8,
|
||||||
|
pub format_type: u8,
|
||||||
|
pub available: Option<bool>,
|
||||||
|
pub guild_id: Option<u64>,
|
||||||
|
pub user: Option<User>,
|
||||||
|
pub sort_value: Option<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct StickerItem {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub name: String,
|
||||||
|
pub format_type: u8,
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::entities::User;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
pub struct Team {
|
||||||
|
pub icon: Option<String>,
|
||||||
|
pub id: u64,
|
||||||
|
pub members: Vec<TeamMember>,
|
||||||
|
pub name: String,
|
||||||
|
pub owner_user_id: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
pub struct TeamMember {
|
||||||
|
pub membership_state: u8,
|
||||||
|
pub permissions: Vec<String>,
|
||||||
|
pub team_id: u64,
|
||||||
|
pub user: User,
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
entities::{Guild, User},
|
||||||
|
utils::Snowflake,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// See https://docs.spacebar.chat/routes/#cmp--schemas-template
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
pub struct GuildTemplate {
|
||||||
|
pub code: String,
|
||||||
|
pub name: String,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub usage_count: Option<u64>,
|
||||||
|
pub creator_id: Snowflake,
|
||||||
|
pub creator: User,
|
||||||
|
pub created_at: DateTime<Utc>,
|
||||||
|
pub updated_at: DateTime<Utc>,
|
||||||
|
pub source_guild_id: String,
|
||||||
|
pub source_guild: Vec<Guild>, // Unsure how a {recursive: Guild} looks like, might be a Vec?
|
||||||
|
pub serialized_source_guild: Vec<Guild>,
|
||||||
|
id: Snowflake,
|
||||||
|
}
|
|
@ -0,0 +1,238 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::{Map, Value};
|
||||||
|
#[cfg(feature = "sqlx")]
|
||||||
|
use sqlx::{FromRow, Type};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
errors::Error,
|
||||||
|
utils::Snowflake, //util::{email::adjust_email, entities::user_setting::UserSettings},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "sqlx", derive(FromRow))]
|
||||||
|
pub struct User {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub username: String,
|
||||||
|
pub discriminator: String,
|
||||||
|
pub avatar: Option<String>,
|
||||||
|
pub accent_color: Option<u8>,
|
||||||
|
pub banner: Option<String>,
|
||||||
|
pub theme_colors: Option<Vec<u8>>,
|
||||||
|
pub pronouns: Option<String>,
|
||||||
|
pub phone: Option<String>,
|
||||||
|
pub desktop: bool,
|
||||||
|
pub mobile: bool,
|
||||||
|
pub premium: bool,
|
||||||
|
pub premium_type: u8,
|
||||||
|
pub bot: bool,
|
||||||
|
pub bio: String,
|
||||||
|
pub system: bool,
|
||||||
|
pub nsfw_allowed: bool,
|
||||||
|
pub mfa_enabled: bool,
|
||||||
|
pub webauthn_enabled: bool,
|
||||||
|
#[serde(skip)]
|
||||||
|
pub totp_secret: Option<String>,
|
||||||
|
#[serde(skip)]
|
||||||
|
pub totp_last_ticket: Option<String>,
|
||||||
|
pub created_at: DateTime<Utc>,
|
||||||
|
pub premium_since: Option<DateTime<Utc>>,
|
||||||
|
pub verified: bool,
|
||||||
|
pub disabled: bool,
|
||||||
|
pub deleted: bool,
|
||||||
|
pub email: Option<String>,
|
||||||
|
pub flags: String,
|
||||||
|
pub public_flags: u16,
|
||||||
|
pub purchased_flags: u16,
|
||||||
|
pub premium_usage_flags: u16,
|
||||||
|
pub rights: String,
|
||||||
|
#[cfg(feature = "sqlx")]
|
||||||
|
pub relationship_ids: sqlx::types::Json<Vec<String>>,
|
||||||
|
#[cfg(not(feature = "sqlx"))]
|
||||||
|
pub relationship_ids: Vec<String>,
|
||||||
|
#[cfg(feature = "sqlx")]
|
||||||
|
pub connected_account_ids: sqlx::types::Json<Vec<String>>,
|
||||||
|
#[cfg(not(feature = "sqlx"))]
|
||||||
|
pub connected_account_ids: Vec<String>,
|
||||||
|
#[cfg(feature = "sqlx")]
|
||||||
|
pub data: sqlx::types::Json<UserData>,
|
||||||
|
#[cfg(not(feature = "sqlx"))]
|
||||||
|
pub data: UserData,
|
||||||
|
#[cfg(feature = "sqlx")]
|
||||||
|
pub fingerprints: sqlx::types::Json<Vec<String>>,
|
||||||
|
#[cfg(not(feature = "sqlx"))]
|
||||||
|
pub fingerprints: Vec<String>,
|
||||||
|
// pub settings: UserSettings,
|
||||||
|
pub extended_settings: Value,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||||
|
#[cfg_attr(feature = "sqlx", derive(Type))]
|
||||||
|
pub struct UserData {
|
||||||
|
pub valid_tokens_since: DateTime<Utc>,
|
||||||
|
pub hash: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for User {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
id: Snowflake::generate(),
|
||||||
|
username: String::new(),
|
||||||
|
discriminator: String::new(),
|
||||||
|
avatar: None,
|
||||||
|
accent_color: None,
|
||||||
|
banner: None,
|
||||||
|
theme_colors: None,
|
||||||
|
pronouns: None,
|
||||||
|
phone: None,
|
||||||
|
desktop: false,
|
||||||
|
mobile: false,
|
||||||
|
premium: false,
|
||||||
|
premium_type: 0,
|
||||||
|
bot: false,
|
||||||
|
bio: String::new(),
|
||||||
|
system: false,
|
||||||
|
nsfw_allowed: false,
|
||||||
|
mfa_enabled: false,
|
||||||
|
webauthn_enabled: false,
|
||||||
|
totp_secret: None,
|
||||||
|
totp_last_ticket: None,
|
||||||
|
created_at: Utc::now(),
|
||||||
|
premium_since: None,
|
||||||
|
verified: false,
|
||||||
|
disabled: false,
|
||||||
|
deleted: false,
|
||||||
|
email: None,
|
||||||
|
flags: String::from("0"),
|
||||||
|
public_flags: 0,
|
||||||
|
purchased_flags: 0,
|
||||||
|
premium_usage_flags: 0,
|
||||||
|
rights: String::new(),
|
||||||
|
relationship_ids: Default::default(),
|
||||||
|
connected_account_ids: Default::default(),
|
||||||
|
data: Default::default(),
|
||||||
|
fingerprints: Default::default(),
|
||||||
|
//settings: UserSettings::default(),
|
||||||
|
extended_settings: Value::Object(Map::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl User {
|
||||||
|
pub fn validate(&mut self) -> Result<(), Error> {
|
||||||
|
/*if let Some(email) = self.email.as_ref() {
|
||||||
|
self.email = Some(adjust_email(email)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.discriminator.len() < 4 {
|
||||||
|
self.discriminator = format!("{:0>4}", self.discriminator);
|
||||||
|
}
|
||||||
|
Ok(())*/
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn generate_discriminator(_username: &str) -> Result<String, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl User {
|
||||||
|
pub fn to_public_user(self) -> PublicUser {
|
||||||
|
PublicUser::from(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
pub struct PrivateUser {
|
||||||
|
pub id: String,
|
||||||
|
username: String,
|
||||||
|
discriminator: String,
|
||||||
|
avatar: Option<String>,
|
||||||
|
bot: bool,
|
||||||
|
system: Option<bool>,
|
||||||
|
mfa_enabled: Option<bool>,
|
||||||
|
accent_color: Option<String>,
|
||||||
|
locale: Option<String>,
|
||||||
|
verified: Option<bool>,
|
||||||
|
email: Option<String>,
|
||||||
|
flags: String,
|
||||||
|
premium_since: Option<String>,
|
||||||
|
premium_type: i8,
|
||||||
|
pronouns: Option<String>,
|
||||||
|
public_flags: Option<i8>,
|
||||||
|
banner: Option<String>,
|
||||||
|
bio: String,
|
||||||
|
theme_colors: Option<Vec<i32>>,
|
||||||
|
phone: Option<String>,
|
||||||
|
nsfw_allowed: bool,
|
||||||
|
premium: bool,
|
||||||
|
purchased_flags: i32,
|
||||||
|
premium_usage_flags: i32,
|
||||||
|
disabled: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct PublicUser {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub username: String,
|
||||||
|
pub discriminator: String,
|
||||||
|
pub avatar: Option<String>,
|
||||||
|
pub accent_color: Option<u8>,
|
||||||
|
pub banner: Option<String>,
|
||||||
|
pub theme_colors: Option<Vec<u8>>,
|
||||||
|
pub pronouns: Option<String>,
|
||||||
|
pub bot: bool,
|
||||||
|
pub bio: String,
|
||||||
|
pub premium_type: u8,
|
||||||
|
pub premium_since: Option<DateTime<Utc>>,
|
||||||
|
pub public_flags: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<User> for PublicUser {
|
||||||
|
fn from(value: User) -> Self {
|
||||||
|
Self {
|
||||||
|
id: value.id,
|
||||||
|
username: value.username,
|
||||||
|
discriminator: value.discriminator,
|
||||||
|
avatar: value.avatar,
|
||||||
|
accent_color: value.accent_color,
|
||||||
|
banner: value.banner,
|
||||||
|
theme_colors: value.theme_colors,
|
||||||
|
pronouns: value.pronouns,
|
||||||
|
bot: value.bot,
|
||||||
|
bio: value.bio,
|
||||||
|
premium_type: value.premium_type,
|
||||||
|
premium_since: value.premium_since,
|
||||||
|
public_flags: value.public_flags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const CUSTOM_USER_FLAG_OFFSET: u64 = 1 << 32;
|
||||||
|
|
||||||
|
bitflags::bitflags! {
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "sqlx", derive(Type))]
|
||||||
|
pub struct UserFlags: u64 {
|
||||||
|
const DISCORD_EMPLOYEE = 1 << 0;
|
||||||
|
const PARTNERED_SERVER_OWNER = 1 << 1;
|
||||||
|
const HYPESQUAD_EVENTS = 1 << 2;
|
||||||
|
const BUGHUNTER_LEVEL_1 =1 << 3;
|
||||||
|
const MFA_SMS = 1 << 4;
|
||||||
|
const PREMIUM_PROMO_DISMISSED = 1 << 5;
|
||||||
|
const HOUSE_BRAVERY = 1 << 6;
|
||||||
|
const HOUSE_BRILLIANCE = 1 << 7;
|
||||||
|
const HOUSE_BALANCE = 1 << 8;
|
||||||
|
const EARLY_SUPPORTER = 1 << 9;
|
||||||
|
const TEAM_USER = 1 << 10;
|
||||||
|
const TRUST_AND_SAFETY = 1 << 11;
|
||||||
|
const SYSTEM = 1 << 12;
|
||||||
|
const HAS_UNREAD_URGENT_MESSAGES = 1 << 13;
|
||||||
|
const BUGHUNTER_LEVEL_2 = 1 << 14;
|
||||||
|
const UNDERAGE_DELETED = 1 << 15;
|
||||||
|
const VERIFIED_BOT = 1 << 16;
|
||||||
|
const EARLY_VERIFIED_BOT_DEVELOPER = 1 << 17;
|
||||||
|
const CERTIFIED_MODERATOR = 1 << 18;
|
||||||
|
const BOT_HTTP_INTERACTIONS = 1 << 19;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
use chrono::{serde::ts_milliseconds_option, Utc};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::utils::Snowflake;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum UserStatus {
|
||||||
|
#[default]
|
||||||
|
Online,
|
||||||
|
Offline,
|
||||||
|
Dnd,
|
||||||
|
Idle,
|
||||||
|
Invisible,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum UserTheme {
|
||||||
|
#[default]
|
||||||
|
Dark,
|
||||||
|
Light,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct UserSettings {
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
pub index: String, // Database relevance only
|
||||||
|
pub afk_timeout: u16,
|
||||||
|
pub allow_accessibility_detection: bool,
|
||||||
|
pub animate_emoji: bool,
|
||||||
|
pub animate_stickers: u8,
|
||||||
|
pub contact_sync_enabled: bool,
|
||||||
|
pub convert_emoticons: bool,
|
||||||
|
pub custom_status: Option<CustomStatus>,
|
||||||
|
pub default_guilds_restricted: bool,
|
||||||
|
pub detect_platform_accounts: bool,
|
||||||
|
pub developer_mode: bool,
|
||||||
|
pub disable_games_tab: bool,
|
||||||
|
pub enable_tts_command: bool,
|
||||||
|
pub explicit_content_filter: u8,
|
||||||
|
pub friend_source_flags: FriendSourceFlags,
|
||||||
|
pub gateway_connected: bool,
|
||||||
|
pub gif_auto_play: bool,
|
||||||
|
pub guild_folders: Vec<GuildFolder>,
|
||||||
|
pub guild_positions: Vec<String>,
|
||||||
|
pub inline_attachment_media: bool,
|
||||||
|
pub inline_embed_media: bool,
|
||||||
|
pub locale: String,
|
||||||
|
pub message_display_compact: bool,
|
||||||
|
pub native_phone_integration_enabled: bool,
|
||||||
|
pub render_embeds: bool,
|
||||||
|
pub render_reactions: bool,
|
||||||
|
pub restricted_guilds: Vec<String>,
|
||||||
|
pub show_current_game: bool,
|
||||||
|
pub status: UserStatus,
|
||||||
|
pub stream_notifications_enabled: bool,
|
||||||
|
pub theme: UserTheme,
|
||||||
|
pub timezone_offset: i16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for UserSettings {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
index: Snowflake::generate().to_string(),
|
||||||
|
afk_timeout: 3600,
|
||||||
|
allow_accessibility_detection: true,
|
||||||
|
animate_emoji: true,
|
||||||
|
animate_stickers: 0,
|
||||||
|
contact_sync_enabled: false,
|
||||||
|
convert_emoticons: false,
|
||||||
|
custom_status: None,
|
||||||
|
default_guilds_restricted: false,
|
||||||
|
detect_platform_accounts: false,
|
||||||
|
developer_mode: true,
|
||||||
|
disable_games_tab: true,
|
||||||
|
enable_tts_command: false,
|
||||||
|
explicit_content_filter: 0,
|
||||||
|
friend_source_flags: FriendSourceFlags::default(),
|
||||||
|
gateway_connected: false,
|
||||||
|
gif_auto_play: false,
|
||||||
|
guild_folders: Vec::new(),
|
||||||
|
guild_positions: Vec::new(),
|
||||||
|
inline_attachment_media: true,
|
||||||
|
inline_embed_media: true,
|
||||||
|
locale: "en-US".to_string(),
|
||||||
|
message_display_compact: false,
|
||||||
|
native_phone_integration_enabled: true,
|
||||||
|
render_embeds: true,
|
||||||
|
render_reactions: true,
|
||||||
|
restricted_guilds: Vec::new(),
|
||||||
|
show_current_game: true,
|
||||||
|
status: UserStatus::Online,
|
||||||
|
stream_notifications_enabled: false,
|
||||||
|
theme: UserTheme::Dark,
|
||||||
|
timezone_offset: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct CustomStatus {
|
||||||
|
pub emoji_id: Option<String>,
|
||||||
|
pub emoji_name: Option<String>,
|
||||||
|
#[serde(with = "ts_milliseconds_option")]
|
||||||
|
pub expires_at: Option<chrono::DateTime<Utc>>,
|
||||||
|
pub text: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct FriendSourceFlags {
|
||||||
|
pub all: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for FriendSourceFlags {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { all: true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct GuildFolder {
|
||||||
|
pub color: u32,
|
||||||
|
pub guild_ids: Vec<String>,
|
||||||
|
pub id: u16,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct LoginResult {
|
||||||
|
pub token: String,
|
||||||
|
pub settings: UserSettings,
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
entities::{Channel, Guild, GuildMember, User},
|
||||||
|
utils::Snowflake,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// See https://docs.spacebar.chat/routes/#cmp--schemas-voicestate
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
pub struct VoiceState {
|
||||||
|
pub guild_id: Snowflake,
|
||||||
|
pub guild: Option<Guild>,
|
||||||
|
pub channel_id: Snowflake,
|
||||||
|
pub channel: Option<Channel>,
|
||||||
|
pub user_id: Snowflake,
|
||||||
|
pub user: Option<User>,
|
||||||
|
pub member: Option<GuildMember>,
|
||||||
|
pub session_id: Snowflake,
|
||||||
|
pub token: String,
|
||||||
|
pub deaf: bool,
|
||||||
|
pub mute: bool,
|
||||||
|
pub self_deaf: bool,
|
||||||
|
pub self_mute: bool,
|
||||||
|
pub self_stream: Option<bool>,
|
||||||
|
pub self_video: bool,
|
||||||
|
pub suppress: bool,
|
||||||
|
pub request_to_speak_timestamp: Option<DateTime<Utc>>,
|
||||||
|
pub id: Snowflake,
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
entities::{Application, Channel, Guild, User},
|
||||||
|
utils::Snowflake,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// See https://docs.spacebar.chat/routes/#cmp--schemas-webhook
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
pub struct Webhook {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub webhook_type: i32,
|
||||||
|
pub name: String,
|
||||||
|
pub avatar: String,
|
||||||
|
pub token: String,
|
||||||
|
pub guild_id: Snowflake,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub guild: Option<Guild>,
|
||||||
|
pub channel_id: Snowflake,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub channel: Option<Channel>,
|
||||||
|
pub application_id: Snowflake,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub application: Option<Application>,
|
||||||
|
pub user_id: Snowflake,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub user: Option<User>,
|
||||||
|
pub source_guild_id: Snowflake,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub source_guild: Option<Guild>,
|
||||||
|
pub id: Snowflake,
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum Error {
|
||||||
|
#[cfg(feature = "sqlx")]
|
||||||
|
#[error("SQLX error: {0}")]
|
||||||
|
SQLX(#[from] sqlx::Error),
|
||||||
|
|
||||||
|
#[error("serde: {0}")]
|
||||||
|
Serde(#[from] serde_json::Error),
|
||||||
|
|
||||||
|
#[error(transparent)]
|
||||||
|
IO(#[from] std::io::Error),
|
||||||
|
|
||||||
|
#[error(transparent)]
|
||||||
|
FieldFormat(#[from] FieldFormatError),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
|
||||||
|
pub enum FieldFormatError {
|
||||||
|
#[error("Password must be between 1 and 72 characters.")]
|
||||||
|
PasswordError,
|
||||||
|
#[error("Username must be between 2 and 32 characters.")]
|
||||||
|
UsernameError,
|
||||||
|
#[error("Consent must be 'true' to register.")]
|
||||||
|
ConsentError,
|
||||||
|
#[error("The provided email address is in an invalid format.")]
|
||||||
|
EmailError,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct ErrorResponse {
|
||||||
|
pub code: i32,
|
||||||
|
pub message: String,
|
||||||
|
pub errors: IntermittentError,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct IntermittentError {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub errors: std::collections::HashMap<String, ErrorField>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||||
|
pub struct ErrorField {
|
||||||
|
#[serde(default)]
|
||||||
|
pub _errors: Vec<APIError>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct APIError {
|
||||||
|
pub message: String,
|
||||||
|
pub code: String,
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
use chrono::{DateTime, Utc};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::entities::Channel;
|
||||||
|
use crate::events::WebSocketEvent;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#channel-pins-update
|
||||||
|
pub struct ChannelPinsUpdate {
|
||||||
|
pub guild_id: Option<String>,
|
||||||
|
pub channel_id: String,
|
||||||
|
pub last_pin_timestamp: Option<DateTime<Utc>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for ChannelPinsUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#channel-create
|
||||||
|
/// Not directly serialized, as the inner payload is a channel object
|
||||||
|
pub struct ChannelCreate {
|
||||||
|
pub channel: Channel,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for ChannelCreate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#channel-update
|
||||||
|
/// Not directly serialized, as the inner payload is a channel object
|
||||||
|
pub struct ChannelUpdate {
|
||||||
|
pub channel: Channel,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for ChannelUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#channel-delete
|
||||||
|
/// Not directly serialized, as the inner payload is a channel object
|
||||||
|
pub struct ChannelDelete {
|
||||||
|
pub channel: Channel,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for ChannelDelete {}
|
|
@ -0,0 +1,41 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::entities::{Guild, UnavailableGuild, User};
|
||||||
|
use crate::events::WebSocketEvent;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-create
|
||||||
|
/// This one is particularly painful, it can be a Guild object with extra field or an unavailbile guild object
|
||||||
|
pub struct GuildCreate {
|
||||||
|
pub d: GuildCreateDataOption,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
pub enum GuildCreateDataOption {
|
||||||
|
UnavailableGuild(UnavailableGuild),
|
||||||
|
Guild(Guild),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GuildCreateDataOption {
|
||||||
|
fn default() -> Self {
|
||||||
|
GuildCreateDataOption::UnavailableGuild(UnavailableGuild::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl WebSocketEvent for GuildCreate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-ban-add-guild-ban-add-event-fields
|
||||||
|
pub struct GuildBanAdd {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub user: User,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildBanAdd {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#guild-ban-remove
|
||||||
|
pub struct GuildBanRemove {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub user: User,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GuildBanRemove {}
|
|
@ -0,0 +1,17 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::events::WebSocketEvent;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
pub struct GatewayHeartbeat {
|
||||||
|
pub op: u8,
|
||||||
|
pub d: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GatewayHeartbeat {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
pub struct GatewayHeartbeatAck {
|
||||||
|
pub op: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GatewayHeartbeatAck {}
|
|
@ -0,0 +1,17 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::events::WebSocketEvent;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
pub struct GatewayHello {
|
||||||
|
pub op: i32,
|
||||||
|
pub d: HelloData,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GatewayHello {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
pub struct HelloData {
|
||||||
|
pub heartbeat_interval: u128,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for HelloData {}
|
|
@ -0,0 +1,22 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::events::{PresenceUpdate, WebSocketEvent};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
pub struct GatewayIdentifyPayload {
|
||||||
|
pub token: String,
|
||||||
|
pub properties: GatewayIdentifyConnectionProps,
|
||||||
|
pub compress: Option<bool>,
|
||||||
|
pub large_threshold: Option<i16>, //default: 50
|
||||||
|
pub shard: Option<Vec<(i32, i32)>>,
|
||||||
|
pub presence: Option<PresenceUpdate>,
|
||||||
|
pub intents: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GatewayIdentifyPayload {}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
pub struct GatewayIdentifyConnectionProps {
|
||||||
|
pub os: String,
|
||||||
|
pub browser: String,
|
||||||
|
pub device: String,
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
entities::{Emoji, GuildMember, Message, User},
|
||||||
|
utils::Snowflake,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::WebSocketEvent;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
pub struct TypingStartEvent {
|
||||||
|
pub channel_id: String,
|
||||||
|
pub guild_id: Option<String>,
|
||||||
|
pub user_id: String,
|
||||||
|
pub timestamp: i64,
|
||||||
|
pub member: Option<GuildMember>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for TypingStartEvent {}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
pub struct MessageCreate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
message: Message,
|
||||||
|
guild_id: Option<Snowflake>,
|
||||||
|
member: Option<GuildMember>,
|
||||||
|
mentions: Vec<(User, GuildMember)>, // Not sure if this is correct: https://discord.com/developers/docs/topics/gateway-events#message-create
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for MessageCreate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
pub struct MessageUpdate {
|
||||||
|
#[serde(flatten)]
|
||||||
|
message: Message,
|
||||||
|
guild_id: Option<String>,
|
||||||
|
member: Option<GuildMember>,
|
||||||
|
mentions: Vec<(User, GuildMember)>, // Not sure if this is correct: https://discord.com/developers/docs/topics/gateway-events#message-create
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for MessageUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
pub struct MessageDelete {
|
||||||
|
id: String,
|
||||||
|
channel_id: String,
|
||||||
|
guild_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for MessageDelete {}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
pub struct MessageDeleteBulk {
|
||||||
|
ids: Vec<String>,
|
||||||
|
channel_id: String,
|
||||||
|
guild_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for MessageDeleteBulk {}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
pub struct MessageReactionAdd {
|
||||||
|
user_id: String,
|
||||||
|
channel_id: String,
|
||||||
|
message_id: String,
|
||||||
|
guild_id: Option<String>,
|
||||||
|
member: Option<GuildMember>,
|
||||||
|
emoji: Emoji,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for MessageReactionAdd {}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
pub struct MessageReactionRemove {
|
||||||
|
user_id: String,
|
||||||
|
channel_id: String,
|
||||||
|
message_id: String,
|
||||||
|
guild_id: Option<String>,
|
||||||
|
emoji: Emoji,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for MessageReactionRemove {}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
pub struct MessageReactionRemoveAll {
|
||||||
|
channel_id: String,
|
||||||
|
message_id: String,
|
||||||
|
guild_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for MessageReactionRemoveAll {}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
pub struct MessageReactionRemoveEmoji {
|
||||||
|
channel_id: String,
|
||||||
|
message_id: String,
|
||||||
|
guild_id: Option<String>,
|
||||||
|
emoji: Emoji,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for MessageReactionRemoveEmoji {}
|
|
@ -0,0 +1,41 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
mod channel;
|
||||||
|
mod guild;
|
||||||
|
mod heartbeat;
|
||||||
|
mod hello;
|
||||||
|
mod identify;
|
||||||
|
mod message;
|
||||||
|
mod presence;
|
||||||
|
mod ready;
|
||||||
|
mod request_members;
|
||||||
|
mod resume;
|
||||||
|
mod thread;
|
||||||
|
mod user;
|
||||||
|
mod voice_status;
|
||||||
|
|
||||||
|
pub use channel::*;
|
||||||
|
pub use guild::*;
|
||||||
|
pub use heartbeat::*;
|
||||||
|
pub use hello::*;
|
||||||
|
pub use identify::*;
|
||||||
|
pub use message::*;
|
||||||
|
pub use presence::*;
|
||||||
|
pub use ready::*;
|
||||||
|
pub use request_members::*;
|
||||||
|
pub use resume::*;
|
||||||
|
pub use thread::*;
|
||||||
|
pub use user::*;
|
||||||
|
pub use voice_status::*;
|
||||||
|
|
||||||
|
pub trait WebSocketEvent {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
pub struct GatewayPayload {
|
||||||
|
pub op: u8,
|
||||||
|
pub d: Option<serde_json::Value>,
|
||||||
|
pub s: Option<u64>,
|
||||||
|
pub t: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GatewayPayload {}
|
|
@ -0,0 +1,24 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::entities::User;
|
||||||
|
use crate::events::WebSocketEvent;
|
||||||
|
use crate::interfaces::Activity;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#presence-update-presence-update-event-fields
|
||||||
|
pub struct PresenceUpdate {
|
||||||
|
pub user: User,
|
||||||
|
pub guild_id: String,
|
||||||
|
pub status: String,
|
||||||
|
pub activities: Vec<Activity>,
|
||||||
|
pub client_status: ClientStatusObject,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#client-status-object
|
||||||
|
pub struct ClientStatusObject {
|
||||||
|
pub desktop: Option<String>,
|
||||||
|
pub mobile: Option<String>,
|
||||||
|
pub web: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for PresenceUpdate {}
|
|
@ -0,0 +1,15 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::entities::{UnavailableGuild, User};
|
||||||
|
use crate::events::WebSocketEvent;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
pub struct GatewayReady {
|
||||||
|
pub v: u8,
|
||||||
|
pub user: User,
|
||||||
|
pub guilds: Vec<UnavailableGuild>,
|
||||||
|
pub session_id: String,
|
||||||
|
pub resume_gateway_url: Option<String>,
|
||||||
|
pub shard: Option<(u64, u64)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GatewayReady {}
|
|
@ -0,0 +1,15 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::events::WebSocketEvent;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#request-guild-members-request-guild-members-structure
|
||||||
|
pub struct GatewayRequestGuildMembers {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub query: Option<String>,
|
||||||
|
pub limit: u64,
|
||||||
|
pub presence: Option<bool>,
|
||||||
|
pub user_ids: Option<String>,
|
||||||
|
pub nonce: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GatewayRequestGuildMembers {}
|
|
@ -0,0 +1,11 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::events::WebSocketEvent;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
pub struct GatewayResume {
|
||||||
|
pub token: String,
|
||||||
|
pub session_id: String,
|
||||||
|
pub seq: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GatewayResume {}
|
|
@ -0,0 +1,82 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::entities::{Channel, GuildMember, ThreadMember};
|
||||||
|
use crate::events::WebSocketEvent;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#thread-create
|
||||||
|
/// Not directly serialized, as the inner payload is a channel object
|
||||||
|
pub struct ThreadCreate {
|
||||||
|
pub thread: Channel,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for ThreadCreate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#thread-update
|
||||||
|
/// Not directly serialized, as the inner payload is a channel object
|
||||||
|
pub struct ThreadUpdate {
|
||||||
|
pub thread: Channel,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for ThreadUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#thread-delete
|
||||||
|
/// Not directly serialized, as the inner payload is a channel object
|
||||||
|
pub struct ThreadDelete {
|
||||||
|
pub thread: Channel,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for ThreadDelete {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#thread-list-sync
|
||||||
|
pub struct ThreadListSync {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub channel_ids: Option<Vec<String>>,
|
||||||
|
pub threads: Vec<Channel>,
|
||||||
|
pub members: Vec<ThreadMember>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for ThreadListSync {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#thread-member-update
|
||||||
|
/// The inner payload is a thread member object with an extra field.
|
||||||
|
/// The extra field is a bit painful, because we can't just serialize a thread member object
|
||||||
|
pub struct ThreadMemberUpdate {
|
||||||
|
pub id: Option<u64>,
|
||||||
|
pub user_id: Option<u64>,
|
||||||
|
pub join_timestamp: Option<String>,
|
||||||
|
pub flags: Option<u64>,
|
||||||
|
pub member: Option<GuildMember>,
|
||||||
|
pub guild_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ThreadMemberUpdate {
|
||||||
|
/// Convert self to a thread member, losing the added guild_id field
|
||||||
|
pub fn to_thread_member(self) -> ThreadMember {
|
||||||
|
ThreadMember {
|
||||||
|
id: self.id,
|
||||||
|
user_id: self.user_id,
|
||||||
|
join_timestamp: self.join_timestamp.clone(),
|
||||||
|
flags: self.flags,
|
||||||
|
member: self.member,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for ThreadMemberUpdate {}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#thread-members-update
|
||||||
|
pub struct ThreadMembersUpdate {
|
||||||
|
pub id: String,
|
||||||
|
pub guild_id: String,
|
||||||
|
/// Capped at 50
|
||||||
|
pub member_count: u8,
|
||||||
|
pub added_members: Option<Vec<ThreadMember>>,
|
||||||
|
pub removed_members: Option<Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for ThreadMembersUpdate {}
|
|
@ -0,0 +1,12 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::entities::User;
|
||||||
|
use crate::events::WebSocketEvent;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#user-update
|
||||||
|
/// Not directly serialized, as the inner payload is the user object
|
||||||
|
pub struct UserUpdate {
|
||||||
|
pub user: User,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for UserUpdate {}
|
|
@ -0,0 +1,13 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::events::WebSocketEvent;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#update-voice-state-gateway-voice-state-update-structure
|
||||||
|
pub struct GatewayVoiceStateUpdate {
|
||||||
|
pub guild_id: String,
|
||||||
|
pub channel_id: Option<String>,
|
||||||
|
pub self_mute: bool,
|
||||||
|
pub self_deaf: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebSocketEvent for GatewayVoiceStateUpdate {}
|
|
@ -0,0 +1,57 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::entities::Emoji;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
pub struct Activity {
|
||||||
|
name: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
activity_type: i32,
|
||||||
|
url: Option<String>,
|
||||||
|
created_at: i64,
|
||||||
|
timestamps: Option<ActivityTimestamps>,
|
||||||
|
application_id: Option<String>,
|
||||||
|
details: Option<String>,
|
||||||
|
state: Option<String>,
|
||||||
|
emoji: Option<Emoji>,
|
||||||
|
party: Option<ActivityParty>,
|
||||||
|
assets: Option<ActivityAssets>,
|
||||||
|
secrets: Option<ActivitySecrets>,
|
||||||
|
instance: Option<bool>,
|
||||||
|
flags: Option<i32>,
|
||||||
|
buttons: Option<Vec<ActivityButton>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
struct ActivityTimestamps {
|
||||||
|
start: Option<i64>,
|
||||||
|
end: Option<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
struct ActivityParty {
|
||||||
|
id: Option<String>,
|
||||||
|
size: Option<Vec<(i32, i32)>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
struct ActivityAssets {
|
||||||
|
large_image: Option<String>,
|
||||||
|
large_text: Option<String>,
|
||||||
|
small_image: Option<String>,
|
||||||
|
small_text: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
struct ActivitySecrets {
|
||||||
|
join: Option<String>,
|
||||||
|
spectate: Option<String>,
|
||||||
|
#[serde(rename = "match")]
|
||||||
|
match_string: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
struct ActivityButton {
|
||||||
|
label: String,
|
||||||
|
url: String,
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::utils::Snowflake;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
pub struct WelcomeScreenObject {
|
||||||
|
pub enabled: bool,
|
||||||
|
pub description: Option<String>,
|
||||||
|
pub welcome_channels: Vec<WelcomeScreenChannel>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||||
|
pub struct WelcomeScreenChannel {
|
||||||
|
pub channel_id: Snowflake,
|
||||||
|
pub description: String,
|
||||||
|
pub emoji_id: Option<Snowflake>,
|
||||||
|
pub emoji_name: Option<String>,
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::Value;
|
||||||
|
use crate::entities::{AllowedMention, Embed};
|
||||||
|
use crate::utils::Snowflake;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Interaction {
|
||||||
|
pub id: Snowflake,
|
||||||
|
pub r#type: InteractionType,
|
||||||
|
pub data: Value,
|
||||||
|
pub guild_id: Snowflake,
|
||||||
|
pub channel_id: Snowflake,
|
||||||
|
pub member_id: Snowflake,
|
||||||
|
pub token: String,
|
||||||
|
pub version: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub enum InteractionType {
|
||||||
|
SelfCommand = 0,
|
||||||
|
Ping = 1,
|
||||||
|
ApplicationCommand = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum InteractionResponseType {
|
||||||
|
SelfCommandResponse = 0,
|
||||||
|
Pong = 1,
|
||||||
|
Acknowledge = 2,
|
||||||
|
ChannelMessage = 3,
|
||||||
|
ChannelMessageWithSource = 4,
|
||||||
|
AcknowledgeWithSource = 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct InteractionApplicationCommandCallbackData {
|
||||||
|
pub tts: bool,
|
||||||
|
pub content: String,
|
||||||
|
pub embeds: Vec<Embed>,
|
||||||
|
pub allowed_mentions: AllowedMention
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
mod activity;
|
||||||
|
mod connected_account;
|
||||||
|
mod guild_welcome_screen;
|
||||||
|
mod interaction;
|
||||||
|
mod status;
|
||||||
|
|
||||||
|
pub use activity::*;
|
||||||
|
pub use connected_account::*;
|
||||||
|
pub use guild_welcome_screen::*;
|
||||||
|
pub use interaction::*;
|
||||||
|
pub use status::*;
|
|
@ -0,0 +1,9 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway-events#client-status-object
|
||||||
|
pub struct ClientStatusObject {
|
||||||
|
pub desktop: Option<String>,
|
||||||
|
pub mobile: Option<String>,
|
||||||
|
pub web: Option<String>,
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
pub mod config; // Maybe feature lock this for backend/web usage only? web would only need it in the case of the admin panel
|
||||||
|
pub mod entities;
|
||||||
|
pub mod errors;
|
||||||
|
pub mod events;
|
||||||
|
pub mod utils;
|
||||||
|
pub mod interfaces;
|
||||||
|
pub mod schema;
|
|
@ -0,0 +1,72 @@
|
||||||
|
#[cfg(feature = "poem")]
|
||||||
|
use poem::{http::StatusCode, IntoResponse, Response};
|
||||||
|
use serde_json::{json, Value};
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum APIError {
|
||||||
|
#[error(transparent)]
|
||||||
|
Auth(#[from] AuthError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl APIError {
|
||||||
|
pub fn error_payload(&self) -> Value {
|
||||||
|
match self {
|
||||||
|
APIError::Auth(auth_err) => auth_err.error_payload(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum AuthError {
|
||||||
|
#[error("INVALID_LOGIN")]
|
||||||
|
InvalidLogin,
|
||||||
|
#[error("INVALID_CAPTCHA")]
|
||||||
|
InvalidCaptcha,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuthError {
|
||||||
|
pub fn error_code(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
AuthError::InvalidLogin => "INVALID_LOGIN",
|
||||||
|
AuthError::InvalidCaptcha => "INVALID_CATPCA",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn error_payload(&self) -> Value {
|
||||||
|
match self {
|
||||||
|
AuthError::InvalidLogin => json!({
|
||||||
|
"login": {
|
||||||
|
"message": "auth:login.INVALID_LOGIN",
|
||||||
|
"code": self.error_code()
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
AuthError::InvalidCaptcha => json!([json!({
|
||||||
|
"captcha_key": "TODO",
|
||||||
|
"captcha_sitekey": "TODO",
|
||||||
|
"captcha_service": "TODO"
|
||||||
|
})]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "poem")]
|
||||||
|
impl poem::error::ResponseError for APIError {
|
||||||
|
fn status(&self) -> StatusCode {
|
||||||
|
match self {
|
||||||
|
APIError::Auth(auth_err) => match auth_err {
|
||||||
|
AuthError::InvalidLogin => StatusCode::UNAUTHORIZED,
|
||||||
|
AuthError::InvalidCaptcha => StatusCode::BAD_REQUEST,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_response(&self) -> Response
|
||||||
|
where
|
||||||
|
Self: std::error::Error + Send + Sync + 'static,
|
||||||
|
{
|
||||||
|
Response::builder()
|
||||||
|
.status(self.status())
|
||||||
|
.body(self.error_payload().to_string())
|
||||||
|
.into_response()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,240 @@
|
||||||
|
use crate::errors::FieldFormatError;
|
||||||
|
use regex::Regex;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/**
|
||||||
|
A struct that represents a well-formed email address.
|
||||||
|
*/
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
|
pub struct AuthEmail {
|
||||||
|
pub email: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuthEmail {
|
||||||
|
/**
|
||||||
|
Returns a new [`Result<AuthEmail, FieldFormatError>`].
|
||||||
|
## Arguments
|
||||||
|
The email address you want to validate.
|
||||||
|
## Errors
|
||||||
|
You will receive a [`FieldFormatError`], if:
|
||||||
|
- The email address is not in a valid format.
|
||||||
|
|
||||||
|
*/
|
||||||
|
pub fn new(email: String) -> Result<AuthEmail, FieldFormatError> {
|
||||||
|
let regex = Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap();
|
||||||
|
if !regex.is_match(email.as_str()) {
|
||||||
|
return Err(FieldFormatError::EmailError);
|
||||||
|
}
|
||||||
|
Ok(AuthEmail { email })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
A struct that represents a well-formed username.
|
||||||
|
## Arguments
|
||||||
|
Please use new() to create a new instance of this struct.
|
||||||
|
## Errors
|
||||||
|
You will receive a [`FieldFormatError`], if:
|
||||||
|
- The username is not between 2 and 32 characters.
|
||||||
|
*/
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
|
pub struct AuthUsername {
|
||||||
|
pub username: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuthUsername {
|
||||||
|
/**
|
||||||
|
Returns a new [`Result<AuthUsername, FieldFormatError>`].
|
||||||
|
## Arguments
|
||||||
|
The username you want to validate.
|
||||||
|
## Errors
|
||||||
|
You will receive a [`FieldFormatError`], if:
|
||||||
|
- The username is not between 2 and 32 characters.
|
||||||
|
*/
|
||||||
|
pub fn new(username: String) -> Result<AuthUsername, FieldFormatError> {
|
||||||
|
if username.len() < 2 || username.len() > 32 {
|
||||||
|
Err(FieldFormatError::UsernameError)
|
||||||
|
} else {
|
||||||
|
Ok(AuthUsername { username })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
A struct that represents a well-formed password.
|
||||||
|
## Arguments
|
||||||
|
Please use new() to create a new instance of this struct.
|
||||||
|
## Errors
|
||||||
|
You will receive a [`FieldFormatError`], if:
|
||||||
|
- The password is not between 1 and 72 characters.
|
||||||
|
*/
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
|
pub struct AuthPassword {
|
||||||
|
pub password: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AuthPassword {
|
||||||
|
/**
|
||||||
|
Returns a new [`Result<AuthPassword, FieldFormatError>`].
|
||||||
|
## Arguments
|
||||||
|
The password you want to validate.
|
||||||
|
## Errors
|
||||||
|
You will receive a [`FieldFormatError`], if:
|
||||||
|
- The password is not between 1 and 72 characters.
|
||||||
|
*/
|
||||||
|
pub fn new(password: String) -> Result<AuthPassword, FieldFormatError> {
|
||||||
|
if password.is_empty() || password.len() > 72 {
|
||||||
|
Err(FieldFormatError::PasswordError)
|
||||||
|
} else {
|
||||||
|
Ok(AuthPassword { password })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
A struct that represents a well-formed register request.
|
||||||
|
## Arguments
|
||||||
|
Please use new() to create a new instance of this struct.
|
||||||
|
## Errors
|
||||||
|
You will receive a [`FieldFormatError`], if:
|
||||||
|
- The username is not between 2 and 32 characters.
|
||||||
|
- The password is not between 1 and 72 characters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub struct RegisterSchema {
|
||||||
|
username: String,
|
||||||
|
password: Option<String>,
|
||||||
|
consent: bool,
|
||||||
|
email: Option<String>,
|
||||||
|
fingerprint: Option<String>,
|
||||||
|
invite: Option<String>,
|
||||||
|
date_of_birth: Option<String>,
|
||||||
|
gift_code_sku_id: Option<String>,
|
||||||
|
captcha_key: Option<String>,
|
||||||
|
promotional_email_opt_in: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RegisterSchema {
|
||||||
|
/**
|
||||||
|
Returns a new [`Result<RegisterSchema, FieldFormatError>`].
|
||||||
|
## Arguments
|
||||||
|
All but "String::username" and "bool::consent" are optional.
|
||||||
|
|
||||||
|
## Errors
|
||||||
|
You will receive a [`FieldFormatError`], if:
|
||||||
|
- The username is less than 2 or more than 32 characters in length
|
||||||
|
- You supply a `password` which is less than 1 or more than 72 characters in length.
|
||||||
|
|
||||||
|
These constraints have been defined [in the Spacebar-API](https://docs.spacebar.chat/routes/)
|
||||||
|
*/
|
||||||
|
pub fn new(
|
||||||
|
username: String,
|
||||||
|
password: Option<String>,
|
||||||
|
consent: bool,
|
||||||
|
email: Option<String>,
|
||||||
|
fingerprint: Option<String>,
|
||||||
|
invite: Option<String>,
|
||||||
|
date_of_birth: Option<String>,
|
||||||
|
gift_code_sku_id: Option<String>,
|
||||||
|
captcha_key: Option<String>,
|
||||||
|
promotional_email_opt_in: Option<bool>,
|
||||||
|
) -> Result<RegisterSchema, FieldFormatError> {
|
||||||
|
let username = AuthUsername::new(username)?.username;
|
||||||
|
|
||||||
|
let email = if let Some(email) = email {
|
||||||
|
Some(AuthEmail::new(email)?.email)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let password = if let Some(password) = password {
|
||||||
|
Some(AuthPassword::new(password)?.password)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
if !consent {
|
||||||
|
return Err(FieldFormatError::ConsentError);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(RegisterSchema {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
consent,
|
||||||
|
email,
|
||||||
|
fingerprint,
|
||||||
|
invite,
|
||||||
|
date_of_birth,
|
||||||
|
gift_code_sku_id,
|
||||||
|
captcha_key,
|
||||||
|
promotional_email_opt_in,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
A struct that represents a well-formed login request.
|
||||||
|
## Arguments
|
||||||
|
Please use new() to create a new instance of this struct.
|
||||||
|
## Errors
|
||||||
|
You will receive a [`FieldFormatError`], if:
|
||||||
|
- The username is not between 2 and 32 characters.
|
||||||
|
- The password is not between 1 and 72 characters.
|
||||||
|
*/
|
||||||
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub struct LoginSchema {
|
||||||
|
pub login: String,
|
||||||
|
pub password: String,
|
||||||
|
pub undelete: Option<bool>,
|
||||||
|
pub captcha_key: Option<String>,
|
||||||
|
pub login_source: Option<String>,
|
||||||
|
pub gift_code_sku_id: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LoginSchema {
|
||||||
|
/**
|
||||||
|
Returns a new [`Result<LoginSchema, FieldFormatError>`].
|
||||||
|
## Arguments
|
||||||
|
login: The username you want to login with.
|
||||||
|
password: The password you want to login with.
|
||||||
|
undelete: Honestly no idea what this is for.
|
||||||
|
captcha_key: The captcha key you want to login with.
|
||||||
|
login_source: The login source.
|
||||||
|
gift_code_sku_id: The gift code sku id.
|
||||||
|
## Errors
|
||||||
|
You will receive a [`FieldFormatError`], if:
|
||||||
|
- The username is less than 2 or more than 32 characters in length
|
||||||
|
*/
|
||||||
|
pub fn new(
|
||||||
|
login: String,
|
||||||
|
password: String,
|
||||||
|
undelete: Option<bool>,
|
||||||
|
captcha_key: Option<String>,
|
||||||
|
login_source: Option<String>,
|
||||||
|
gift_code_sku_id: Option<String>,
|
||||||
|
) -> Result<LoginSchema, FieldFormatError> {
|
||||||
|
let login = AuthUsername::new(login)?.username;
|
||||||
|
let password = AuthPassword::new(password)?.password;
|
||||||
|
|
||||||
|
Ok(LoginSchema {
|
||||||
|
login,
|
||||||
|
password,
|
||||||
|
undelete,
|
||||||
|
captcha_key,
|
||||||
|
login_source,
|
||||||
|
gift_code_sku_id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub struct TotpSchema {
|
||||||
|
code: String,
|
||||||
|
ticket: String,
|
||||||
|
gift_code_sku_id: Option<String>,
|
||||||
|
login_source: Option<String>,
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::entities::PermissionOverwrite;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub struct ChannelCreateSchema {
|
||||||
|
pub name: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub channel_type: Option<u8>,
|
||||||
|
pub topic: Option<String>,
|
||||||
|
pub icon: Option<String>,
|
||||||
|
pub bitrate: Option<i32>,
|
||||||
|
pub user_limit: Option<i32>,
|
||||||
|
pub rate_limit_per_user: Option<i32>,
|
||||||
|
pub position: Option<i32>,
|
||||||
|
pub permission_overwrites: Option<Vec<PermissionOverwrite>>,
|
||||||
|
pub parent_id: Option<String>,
|
||||||
|
pub id: Option<String>,
|
||||||
|
pub nsfw: Option<bool>,
|
||||||
|
pub rtc_region: Option<String>,
|
||||||
|
pub default_auto_archive_duration: Option<i32>,
|
||||||
|
pub default_reaction_emoji: Option<String>,
|
||||||
|
pub flags: Option<i32>,
|
||||||
|
pub default_thread_rate_limit_per_user: Option<i32>,
|
||||||
|
pub video_quality_mode: Option<i32>,
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::entities::Channel;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub struct GuildCreateSchema {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub region: Option<String>,
|
||||||
|
pub icon: Option<String>,
|
||||||
|
pub channels: Option<Vec<Channel>>,
|
||||||
|
pub guild_template_code: Option<String>,
|
||||||
|
pub system_channel_id: Option<String>,
|
||||||
|
pub rules_channel_id: Option<String>,
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use crate::entities::{AllowedMention, Component, Embed, MessageReference, PartialDiscordFileAttachment};
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub struct MessageSendSchema {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
message_type: Option<i32>,
|
||||||
|
content: Option<String>,
|
||||||
|
nonce: Option<String>,
|
||||||
|
tts: Option<bool>,
|
||||||
|
embeds: Option<Vec<Embed>>,
|
||||||
|
allowed_mentions: Option<AllowedMention>,
|
||||||
|
message_reference: Option<MessageReference>,
|
||||||
|
components: Option<Vec<Component>>,
|
||||||
|
sticker_ids: Option<Vec<String>>,
|
||||||
|
pub attachments: Option<Vec<PartialDiscordFileAttachment>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
// make a new() method for MessageSendSchema
|
||||||
|
impl MessageSendSchema {
|
||||||
|
pub fn new(
|
||||||
|
message_type: Option<i32>,
|
||||||
|
content: Option<String>,
|
||||||
|
nonce: Option<String>,
|
||||||
|
tts: Option<bool>,
|
||||||
|
embeds: Option<Vec<Embed>>,
|
||||||
|
allowed_mentions: Option<AllowedMention>,
|
||||||
|
message_reference: Option<MessageReference>,
|
||||||
|
components: Option<Vec<Component>>,
|
||||||
|
sticker_ids: Option<Vec<String>>,
|
||||||
|
attachments: Option<Vec<PartialDiscordFileAttachment>>,
|
||||||
|
) -> MessageSendSchema {
|
||||||
|
MessageSendSchema {
|
||||||
|
message_type,
|
||||||
|
content,
|
||||||
|
nonce,
|
||||||
|
tts,
|
||||||
|
embeds,
|
||||||
|
allowed_mentions,
|
||||||
|
message_reference,
|
||||||
|
components,
|
||||||
|
sticker_ids,
|
||||||
|
attachments,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue