use std::collections::HashMap;
mod command;
pub use command::*;
mod command_interaction;
pub use command_interaction::*;
mod component;
pub use component::*;
mod component_interaction;
pub use component_interaction::*;
mod interaction;
pub use interaction::*;
mod modal_interaction;
pub use modal_interaction::*;
mod oauth;
pub use oauth::*;
mod ping_interaction;
pub use ping_interaction::*;
use super::guild::PartialGuild;
use super::id::{ApplicationId, GenericId, GuildId, SkuId, UserId};
use super::misc::ImageHash;
use super::user::User;
use super::Permissions;
#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct PartialCurrentApplicationInfo {
pub id: ApplicationId,
pub flags: ApplicationFlags,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct CurrentApplicationInfo {
pub id: ApplicationId,
pub name: String,
pub icon: Option<ImageHash>,
pub description: String,
#[serde(default)]
pub rpc_origins: Vec<String>,
pub bot_public: bool,
pub bot_require_code_grant: bool,
#[serde(default)]
pub terms_of_service_url: Option<String>,
#[serde(default)]
pub privacy_policy_url: Option<String>,
pub owner: Option<User>,
pub verify_key: String,
pub team: Option<Team>,
#[serde(default)]
pub guild_id: Option<GuildId>,
#[serde(default)]
pub primary_sku_id: Option<SkuId>,
#[serde(default)]
pub slug: Option<String>,
#[serde(default)]
pub cover_image: Option<String>,
#[serde(default)]
pub flags: Option<ApplicationFlags>,
#[serde(default)]
pub tags: Option<Vec<String>>,
#[serde(default)]
pub install_params: Option<InstallParams>,
#[serde(default)]
pub custom_install_url: Option<String>,
pub role_connections_verification_url: Option<String>,
#[serde(default)]
pub integration_types_config: HashMap<InstallationContext, InstallationContextConfig>,
pub approximate_guild_count: Option<u32>,
pub approximate_user_install_count: Option<u32>,
pub guild: Option<PartialGuild>,
pub redirect_uris: Option<Vec<String>>,
pub interactions_endpoint_url: Option<String>,
}
impl CurrentApplicationInfo {
#[must_use]
pub fn store_url(&self) -> String {
format!("https://discord.com/application-directory/{}/store", self.id)
}
}
enum_number! {
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Deserialize, Serialize)]
#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
#[serde(from = "u8", into = "u8")]
#[non_exhaustive]
pub enum InstallationContext {
Guild = 0,
User = 1,
_ => Unknown(u8),
}
}
enum_number! {
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Deserialize, Serialize)]
#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
#[serde(from = "u8", into = "u8")]
#[non_exhaustive]
pub enum InteractionContext {
Guild = 0,
BotDm = 1,
PrivateChannel = 2,
_ => Unknown(u8),
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct InstallationContextConfig {
pub oauth2_install_params: Option<InstallParams>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct Team {
pub icon: Option<ImageHash>,
pub id: GenericId,
pub name: String,
pub members: Vec<TeamMember>,
pub owner_user_id: UserId,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct TeamMember {
pub membership_state: MembershipState,
#[deprecated = "This field is not sent by the API anymore"]
pub permissions: Vec<String>,
pub team_id: GenericId,
pub user: User,
pub role: TeamMemberRole,
}
enum_number! {
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Deserialize, Serialize)]
#[serde(from = "u8", into = "u8")]
#[non_exhaustive]
pub enum MembershipState {
Invited = 1,
Accepted = 2,
_ => Unknown(u8),
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum TeamMemberRole {
Admin,
Developer,
ReadOnly,
#[serde(untagged)]
Other(String),
}
impl TeamMemberRole {
fn discriminant(&self) -> u8 {
match self {
Self::Admin => 3,
Self::Developer => 2,
Self::ReadOnly => 1,
Self::Other(_) => 0,
}
}
}
impl PartialEq for TeamMemberRole {
fn eq(&self, other: &Self) -> bool {
self.discriminant() == other.discriminant()
}
}
impl Eq for TeamMemberRole {}
impl PartialOrd for TeamMemberRole {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for TeamMemberRole {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.discriminant().cmp(&other.discriminant())
}
}
bitflags! {
#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
#[derive(Copy, Clone, Default, Debug, Eq, Hash, PartialEq)]
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 << 19;
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct InstallParams {
pub scopes: Vec<Scope>,
pub permissions: Permissions,
}
#[cfg(test)]
mod team_role_ordering {
use super::TeamMemberRole;
fn other(val: &str) -> TeamMemberRole {
TeamMemberRole::Other(String::from(val))
}
#[test]
fn test_normal_ordering() {
let mut roles = [
TeamMemberRole::Developer,
TeamMemberRole::Admin,
other(""),
TeamMemberRole::ReadOnly,
other("test"),
];
roles.sort();
assert_eq!(roles, [
other(""),
other("test"),
TeamMemberRole::ReadOnly,
TeamMemberRole::Developer,
TeamMemberRole::Admin,
]);
}
#[test]
fn test_other_eq() {
assert_eq!(other("").cmp(&other("")), std::cmp::Ordering::Equal);
}
}