use bitflags::bitflags;
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use crate::{
Mentionable,
types::{Member, Permissions, Snowflake, User},
};
#[derive(Debug, Clone, Deserialize)]
pub struct PartialChannel {
pub id: Snowflake,
#[serde(rename = "type")]
pub t: ChannelType,
pub name: Option<String>,
pub permissions: Option<Permissions>,
pub thread_metadata: Option<ThreadMetadata>,
pub parent_id: Option<Snowflake>,
}
impl Mentionable for PartialChannel {
fn to_mention(&self) -> String {
format!("<#{}>", self.id)
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct Channel {
pub id: Snowflake,
#[serde(rename = "type")]
pub t: ChannelType,
pub guild_id: Option<Snowflake>,
pub position: Option<i32>,
pub permission_overwrites: Option<Vec<Overwrite>>,
pub name: Option<String>,
pub topic: Option<String>,
pub nsfw: Option<bool>,
pub last_message_id: Option<Snowflake>,
pub bitrate: Option<u32>,
pub user_limit: Option<u32>,
pub rate_limit_per_user: Option<u32>,
pub recipients: Option<Vec<User>>,
pub icon: Option<String>,
pub owner_id: Option<Snowflake>,
pub application_id: Option<Snowflake>,
pub managed: Option<bool>,
pub parent_id: Option<Snowflake>,
pub last_pin_timestamp: Option<String>,
pub rtc_region: Option<String>,
pub video_quality_mode: Option<VideoQualityMode>,
pub message_count: Option<u32>,
pub member_count: Option<u8>,
pub thread_metadata: Option<ThreadMetadata>,
pub member: Option<ThreadMember>,
pub default_auto_archive_duration: Option<u32>,
pub permissions: Option<Permissions>,
pub flags: Option<ChannelFlags>,
pub total_message_sent: Option<u32>,
pub available_tags: Option<Vec<ForumTag>>,
pub applied_tags: Option<Vec<Snowflake>>,
pub default_reaction_emoji: Option<DefaultReaction>,
pub default_thread_rate_limit_per_user: Option<u32>,
pub default_sort_order: Option<SortOrderType>,
pub default_forum_layout: Option<ForumLayoutType>,
}
impl Mentionable for Channel {
fn to_mention(&self) -> String {
format!("<#{}>", self.id)
}
}
impl PartialEq for Channel {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
#[derive(Debug, Clone, Copy, Deserialize_repr, Serialize_repr, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum ChannelType {
GuildText = 0,
Dm = 1,
GuildVoice = 2,
GroupDm = 3,
GuildCategory = 4,
GuildAnnouncement = 5,
AnnouncementThread = 10,
PublicThread = 11,
PrivateThread = 12,
GuildStageVoice = 13,
GuildDirectory = 14,
GuildForum = 15,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize_repr, Serialize_repr)]
#[repr(u8)]
pub enum VideoQualityMode {
Auto = 1,
Full = 2,
}
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ChannelFlags: u32 {
const Pinned = 1 << 1;
const RequireTag = 1 << 4;
}
}
impl Serialize for ChannelFlags {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u32(self.bits())
}
}
impl<'de> Deserialize<'de> for ChannelFlags {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let bits = u32::deserialize(deserializer)?;
Ok(ChannelFlags::from_bits_retain(bits))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize_repr, Serialize_repr)]
#[repr(u8)]
pub enum SortOrderType {
LatestActivity = 0,
CreationDate = 1,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize_repr, Serialize_repr)]
#[repr(u8)]
pub enum ForumLayoutType {
NotSet = 0,
ListView = 1,
GalleryView = 2,
}
#[derive(Debug, Clone, Deserialize)]
pub struct FollowedChannel {
pub channel_id: Snowflake,
pub webhook_id: Snowflake,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Overwrite {
pub id: Snowflake,
#[serde(rename = "type")]
pub t: OverwriteType,
pub allow: Permissions,
pub deny: Permissions,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize_repr, Serialize_repr)]
#[repr(u8)]
pub enum OverwriteType {
Role = 0,
Member = 1,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ThreadMetadata {
pub archived: bool,
pub auto_archive_duration: u16,
pub archive_timestamp: String,
pub locked: bool,
pub invitable: Option<bool>,
pub create_timestamp: Option<String>,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ThreadList {
pub threads: Vec<Channel>,
pub members: Vec<ThreadMember>,
#[serde(default)]
pub has_more: bool,
}
#[derive(Debug, Clone, Deserialize)]
pub struct ThreadMember {
pub id: Option<Snowflake>,
pub user_id: Option<Snowflake>,
pub join_timestamp: String,
pub flags: u32,
pub member: Option<Member>,
}
impl PartialEq for ThreadMember {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ForumTag {
pub id: Snowflake,
pub name: String,
pub moderated: bool,
pub emoji_id: Option<Snowflake>,
pub emoji_name: Option<String>,
}
impl PartialEq for ForumTag {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct DefaultReaction {
pub emoji_id: Option<Snowflake>,
pub emoji_name: Option<String>,
}
impl PartialEq for DefaultReaction {
fn eq(&self, other: &Self) -> bool {
self.emoji_id == other.emoji_id
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
pub fn can_deserialize_channel_type() {
let channel_type_json = "0";
let channel_type = serde_json::from_str::<ChannelType>(channel_type_json).unwrap();
assert_eq!(channel_type, ChannelType::GuildText);
}
#[test]
pub fn can_deserialize_channel() {
let channel_json = r#"{
"flags": 0,
"guild_id": "798662131062931547",
"id": "941169456686723122",
"last_message_id": "1100155827400229026",
"name": "bot-stuff",
"nsfw": false,
"parent_id": "798662131678969866",
"permissions": "140737488355327",
"position": 1,
"rate_limit_per_user": 0,
"topic": null,
"type": 0
}"#;
let channel = serde_json::from_str::<Channel>(channel_json);
let channel = channel.unwrap();
println!("{:#?}", channel);
}
#[test]
fn rest_channels_with_integer_enums() {
let channel: Channel = serde_json::from_value(serde_json::json!({
"id": "1", "type": 2, "video_quality_mode": 2, "bitrate": 64000,
"permission_overwrites": [{ "id": "2", "type": 0, "allow": "1024", "deny": "0" }],
}))
.unwrap();
assert_eq!(channel.video_quality_mode, Some(VideoQualityMode::Full));
let forum: Channel = serde_json::from_value(serde_json::json!({
"id": "1", "type": 15, "default_sort_order": 1, "default_forum_layout": 2,
}))
.unwrap();
assert_eq!(
forum.default_forum_layout,
Some(ForumLayoutType::GalleryView)
);
let overwrite = &channel.permission_overwrites.unwrap()[0];
assert_eq!(
serde_json::to_value(overwrite).unwrap(),
serde_json::json!({ "id": "2", "type": 0, "allow": "1024", "deny": "0" })
);
}
}