use serde::{Deserialize, Serialize};
use serde_json::Value;
pub type Id = String;
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct User {
pub id: Id,
pub username: String,
pub display_name: String,
pub avatar: Option<String>,
pub bot: bool,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Profile {
pub user: User,
pub bio: Option<String>,
pub banner: Option<String>,
pub accent: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Guild {
pub id: Id,
pub name: String,
pub icon: Option<String>,
pub owner_id: Id,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct GuildFull {
pub id: Id,
pub name: String,
pub icon: Option<String>,
pub owner_id: Id,
pub channels: Vec<Channel>,
pub members: Vec<Member>,
pub presences: Vec<Id>,
pub roles: Vec<Role>,
pub emojis: Vec<Emoji>,
}
pub struct ChannelType;
impl ChannelType {
pub const TEXT: u8 = 0;
pub const DM: u8 = 1;
pub const VOICE: u8 = 2;
pub const CATEGORY: u8 = 4;
pub const POST: u8 = 11;
pub const FORUM: u8 = 15;
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct Overwrite {
pub id: Id,
#[serde(rename = "type")]
pub kind: u8,
pub allow: u64,
pub deny: u64,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct ForumTag {
pub id: Id,
pub name: String,
pub emoji: Option<String>,
pub moderated: bool,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Channel {
pub id: Id,
pub guild_id: Option<Id>,
#[serde(rename = "type")]
pub kind: u8,
pub name: String,
pub topic: Option<String>,
pub position: i64,
pub parent_id: Option<Id>,
pub last_message_id: Option<Id>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rate_limit_per_user: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub owner_id: Option<Id>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pinned: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub locked: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message_count: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub applied_tags: Option<Vec<Id>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub voice_server: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub available_tags: Option<Vec<ForumTag>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub recipients: Option<Vec<User>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub permission_overwrites: Option<Vec<Overwrite>>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Member {
pub guild_id: Id,
pub user: User,
pub nick: Option<String>,
pub is_admin: bool,
pub joined_at: i64,
pub roles: Vec<Id>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Role {
pub id: Id,
pub guild_id: Id,
pub name: String,
pub color: Option<u32>,
pub position: i64,
pub permissions: u64,
pub hoist: bool,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Emoji {
pub id: Id,
pub guild_id: Id,
pub name: String,
pub url: String,
pub animated: bool,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Attachment {
pub id: Id,
pub filename: String,
pub content_type: String,
pub size: u64,
pub url: String,
pub thumbnail: Option<String>,
pub width: Option<u32>,
pub height: Option<u32>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct ReactionCount {
pub emoji: String,
pub count: u64,
pub me: bool,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct MessageRef {
pub id: Id,
pub author: Option<User>,
pub content: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Embed {
pub url: String,
pub site_name: Option<String>,
pub title: Option<String>,
pub description: Option<String>,
pub author: Option<String>,
pub color: Option<String>,
pub image: Option<Value>,
pub video: Option<Value>,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct CardAuthor {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub icon_url: Option<String>,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct CardField {
pub name: String,
pub value: String,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub inline: bool,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct CardImage {
pub url: String,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct CardFooter {
pub text: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub icon_url: Option<String>,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct Card {
#[serde(skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub color: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub author: Option<CardAuthor>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub fields: Vec<CardField>,
#[serde(skip_serializing_if = "Option::is_none")]
pub image: Option<CardImage>,
#[serde(skip_serializing_if = "Option::is_none")]
pub thumbnail: Option<CardImage>,
#[serde(skip_serializing_if = "Option::is_none")]
pub footer: Option<CardFooter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timestamp: Option<i64>,
}
impl Card {
pub fn new() -> Self {
Self::default()
}
pub fn title(mut self, title: impl Into<String>) -> Self {
self.title = Some(title.into());
self
}
pub fn description(mut self, text: impl Into<String>) -> Self {
self.description = Some(text.into());
self
}
pub fn url(mut self, url: impl Into<String>) -> Self {
self.url = Some(url.into());
self
}
pub fn color(mut self, color: u32) -> Self {
self.color = Some(color);
self
}
pub fn author(mut self, name: impl Into<String>) -> Self {
self.author = Some(CardAuthor {
name: name.into(),
..Default::default()
});
self
}
pub fn field(
mut self,
name: impl Into<String>,
value: impl Into<String>,
inline: bool,
) -> Self {
self.fields.push(CardField {
name: name.into(),
value: value.into(),
inline,
});
self
}
pub fn image(mut self, url: impl Into<String>) -> Self {
self.image = Some(CardImage { url: url.into() });
self
}
pub fn thumbnail(mut self, url: impl Into<String>) -> Self {
self.thumbnail = Some(CardImage { url: url.into() });
self
}
pub fn footer(mut self, text: impl Into<String>) -> Self {
self.footer = Some(CardFooter {
text: text.into(),
icon_url: None,
});
self
}
pub fn timestamp(mut self, ms: i64) -> Self {
self.timestamp = Some(ms);
self
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ButtonStyle {
#[default]
Primary,
Secondary,
Success,
Danger,
Link,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct Button {
pub style: ButtonStyle,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub emoji: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub custom_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub disabled: bool,
}
impl Button {
pub fn new(style: ButtonStyle, label: impl Into<String>, custom_id: impl Into<String>) -> Self {
Self {
style,
label: Some(label.into()),
custom_id: Some(custom_id.into()),
..Default::default()
}
}
pub fn primary(label: impl Into<String>, custom_id: impl Into<String>) -> Self {
Self::new(ButtonStyle::Primary, label, custom_id)
}
pub fn secondary(label: impl Into<String>, custom_id: impl Into<String>) -> Self {
Self::new(ButtonStyle::Secondary, label, custom_id)
}
pub fn success(label: impl Into<String>, custom_id: impl Into<String>) -> Self {
Self::new(ButtonStyle::Success, label, custom_id)
}
pub fn danger(label: impl Into<String>, custom_id: impl Into<String>) -> Self {
Self::new(ButtonStyle::Danger, label, custom_id)
}
pub fn link(label: impl Into<String>, url: impl Into<String>) -> Self {
Self {
style: ButtonStyle::Link,
label: Some(label.into()),
url: Some(url.into()),
..Default::default()
}
}
pub fn emoji(mut self, emoji: impl Into<String>) -> Self {
self.emoji = Some(emoji.into());
self
}
pub fn disabled(mut self, disabled: bool) -> Self {
self.disabled = disabled;
self
}
}
pub type Components = Vec<Vec<Button>>;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct InteractionRef {
pub id: Id,
pub name: Option<String>,
pub user: User,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum OptionType {
#[default]
String,
Integer,
Number,
Boolean,
User,
Channel,
Role,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct CommandChoice {
pub name: String,
pub value: Value,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct CommandOption {
pub name: String,
pub description: String,
#[serde(rename = "type")]
pub kind: OptionType,
#[serde(skip_serializing_if = "std::ops::Not::not")]
pub required: bool,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub choices: Vec<CommandChoice>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_value: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_value: Option<f64>,
}
impl CommandOption {
pub fn new(name: impl Into<String>, description: impl Into<String>, kind: OptionType) -> Self {
Self {
name: name.into(),
description: description.into(),
kind,
..Default::default()
}
}
pub fn required(mut self) -> Self {
self.required = true;
self
}
pub fn choice(mut self, name: impl Into<String>, value: impl Into<Value>) -> Self {
self.choices.push(CommandChoice {
name: name.into(),
value: value.into(),
});
self
}
pub fn min(mut self, v: f64) -> Self {
self.min_value = Some(v);
self
}
pub fn max(mut self, v: f64) -> Self {
self.max_value = Some(v);
self
}
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct Command {
pub name: String,
pub description: String,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub options: Vec<CommandOption>,
}
impl Command {
pub fn new(name: impl Into<String>, description: impl Into<String>) -> Self {
Self {
name: name.into(),
description: description.into(),
options: Vec::new(),
}
}
pub fn option(mut self, option: CommandOption) -> Self {
self.options.push(option);
self
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum InteractionType {
#[default]
Command,
Button,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct CommandOptionValue {
pub name: String,
#[serde(rename = "type")]
pub kind: OptionType,
pub value: Value,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct InteractionCommand {
pub name: String,
pub options: Vec<CommandOptionValue>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct InteractionData {
pub id: Id,
pub token: String,
#[serde(rename = "type")]
pub kind: InteractionType,
pub channel_id: Id,
pub guild_id: Option<Id>,
pub user: User,
pub member: Option<Member>,
pub command: Option<InteractionCommand>,
pub custom_id: Option<String>,
pub message: Option<MessageData>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct MessageData {
pub id: Id,
pub channel_id: Id,
pub author: User,
pub content: String,
pub timestamp: i64,
pub edited_timestamp: Option<i64>,
pub reply_to: Option<MessageRef>,
pub attachments: Vec<Attachment>,
pub reactions: Vec<ReactionCount>,
pub nonce: Option<String>,
pub embeds: Vec<Embed>,
pub cards: Vec<Card>,
pub components: Components,
pub interaction: Option<InteractionRef>,
pub ephemeral: bool,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Invite {
pub code: String,
pub guild_id: Id,
pub creator_id: Id,
pub uses: u64,
pub max_uses: Option<u64>,
pub expires_at: Option<i64>,
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct VoiceState {
pub user_id: Id,
pub guild_id: Option<Id>,
pub channel_id: Option<Id>,
pub self_mute: bool,
pub self_deaf: bool,
pub self_stream: bool,
pub self_video: bool,
pub session_id: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct Ready {
pub user: User,
pub guilds: Vec<GuildFull>,
pub dm_channels: Vec<Channel>,
pub presences: Vec<Id>,
pub voice_states: Vec<VoiceState>,
pub session_id: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct ReactionEvent {
pub message_id: Id,
pub channel_id: Id,
pub user_id: Id,
pub emoji: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct TypingEvent {
pub channel_id: Id,
pub user_id: Id,
pub timestamp: i64,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct MessageDeleteEvent {
pub id: Id,
pub channel_id: Id,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct MemberRemoveEvent {
pub guild_id: Id,
pub user_id: Id,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct PresenceEvent {
pub user_id: Id,
pub status: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(default)]
pub struct VoiceJoin {
pub url: String,
pub server: Option<String>,
pub token: String,
pub room: String,
pub can_speak: Option<bool>,
pub can_stream: Option<bool>,
}