use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
use super::utils::U64Visitor;
use bitflags::__impl_bitflags;
use std::fmt::{Display, Formatter, Result as FmtResult};
macro_rules! generate_get_permission_names {
{$ ($perm:ident: $name:expr),*} => {
impl Permissions {
pub fn get_permission_names(self) -> Vec<&'static str> {
let mut names = Vec::new();
$(
if self.$perm() {
names.push($name);
}
)*
names
}
}
}
}
pub const PRESET_GENERAL: Permissions = Permissions {
bits: 0b0000_0110_0011_0111_1101_1100_0100_0001,
};
pub const PRESET_TEXT: Permissions = Permissions {
bits: 0b0000_0000_0000_0111_1111_1100_0100_0000,
};
pub const PRESET_VOICE: Permissions = Permissions {
bits: 0b0000_0011_1111_0000_0000_0000_0000_0000,
};
#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
pub struct Permissions {
pub bits: u64
}
__impl_bitflags! {
Permissions: u64 {
CREATE_INVITE = 0b0000_0000_0000_0000_0000_0000_0000_0001;
KICK_MEMBERS = 0b0000_0000_0000_0000_0000_0000_0000_0010;
BAN_MEMBERS = 0b0000_0000_0000_0000_0000_0000_0000_0100;
ADMINISTRATOR = 0b0000_0000_0000_0000_0000_0000_0000_1000;
MANAGE_CHANNELS = 0b0000_0000_0000_0000_0000_0000_0001_0000;
MANAGE_GUILD = 0b0000_0000_0000_0000_0000_0000_0010_0000;
ADD_REACTIONS = 0b0000_0000_0000_0000_0000_0000_0100_0000;
VIEW_AUDIT_LOG = 0b0000_0000_0000_0000_0000_0000_1000_0000;
PRIORITY_SPEAKER = 0b0000_0000_0000_0000_0000_0001_0000_0000;
STREAM = 0b0000_0000_0000_0000_0000_0010_0000_0000;
READ_MESSAGES = 0b0000_0000_0000_0000_0000_0100_0000_0000;
SEND_MESSAGES = 0b0000_0000_0000_0000_0000_1000_0000_0000;
SEND_TTS_MESSAGES = 0b0000_0000_0000_0000_0001_0000_0000_0000;
MANAGE_MESSAGES = 0b0000_0000_0000_0000_0010_0000_0000_0000;
EMBED_LINKS = 0b0000_0000_0000_0000_0100_0000_0000_0000;
ATTACH_FILES = 0b0000_0000_0000_0000_1000_0000_0000_0000;
READ_MESSAGE_HISTORY = 0b0000_0000_0000_0001_0000_0000_0000_0000;
MENTION_EVERYONE = 0b0000_0000_0000_0010_0000_0000_0000_0000;
USE_EXTERNAL_EMOJIS = 0b0000_0000_0000_0100_0000_0000_0000_0000;
CONNECT = 0b0000_0000_0001_0000_0000_0000_0000_0000;
SPEAK = 0b0000_0000_0010_0000_0000_0000_0000_0000;
MUTE_MEMBERS = 0b0000_0000_0100_0000_0000_0000_0000_0000;
DEAFEN_MEMBERS = 0b0000_0000_1000_0000_0000_0000_0000_0000;
MOVE_MEMBERS = 0b0000_0001_0000_0000_0000_0000_0000_0000;
USE_VAD = 0b0000_0010_0000_0000_0000_0000_0000_0000;
CHANGE_NICKNAME = 0b0000_0100_0000_0000_0000_0000_0000_0000;
MANAGE_NICKNAMES = 0b0000_1000_0000_0000_0000_0000_0000_0000;
MANAGE_ROLES = 0b0001_0000_0000_0000_0000_0000_0000_0000;
MANAGE_WEBHOOKS = 0b0010_0000_0000_0000_0000_0000_0000_0000;
MANAGE_EMOJIS = 0b0100_0000_0000_0000_0000_0000_0000_0000;
}
}
generate_get_permission_names! {
add_reactions: "Add Reactions",
administrator: "Administrator",
attach_files: "Attach Files",
ban_members: "Ban Members",
change_nickname: "Change Nickname",
connect: "Connect",
create_invite: "Create Invite",
deafen_members: "Deafen Members",
embed_links: "Embed Links",
external_emojis: "Use External Emojis",
kick_members: "Kick Members",
manage_channels: "Manage Channels",
manage_emojis: "Manage Emojis",
manage_guild: "Manage Guilds",
manage_messages: "Manage Messages",
manage_nicknames: "Manage Nicknames",
manage_roles: "Manage Roles",
manage_webhooks: "Manage Webhooks",
mention_everyone: "Mention Everyone",
move_members: "Move Members",
mute_members: "Mute Members",
priority_speaker: "Priority Speaker",
read_message_history: "Read Message History",
read_messages: "Read Messages",
send_messages: "Send Messages",
send_tts_messages: "Send TTS Messages",
speak: "Speak",
stream: "Stream",
use_external_emojis: "Use External Emojis",
use_vad: "Use Voice Activity",
view_audit_log: "View Audit Log"
}
#[cfg(feature = "model")]
impl Permissions {
pub fn add_reactions(self) -> bool { self.contains(Self::ADD_REACTIONS) }
pub fn administrator(self) -> bool { self.contains(Self::ADMINISTRATOR) }
pub fn attach_files(self) -> bool { self.contains(Self::ATTACH_FILES) }
pub fn ban_members(self) -> bool { self.contains(Self::BAN_MEMBERS) }
pub fn change_nickname(self) -> bool { self.contains(Self::CHANGE_NICKNAME) }
pub fn connect(self) -> bool { self.contains(Self::CONNECT) }
pub fn view_audit_log(self) -> bool { self.contains(Self::VIEW_AUDIT_LOG) }
pub fn priority_speaker(self) -> bool { self.contains(Self::PRIORITY_SPEAKER) }
pub fn stream(self) -> bool { self.contains(Self::STREAM) }
pub fn create_invite(self) -> bool { self.contains(Self::CREATE_INVITE) }
pub fn deafen_members(self) -> bool { self.contains(Self::DEAFEN_MEMBERS) }
pub fn embed_links(self) -> bool { self.contains(Self::EMBED_LINKS) }
pub fn external_emojis(self) -> bool { self.contains(Self::USE_EXTERNAL_EMOJIS) }
pub fn kick_members(self) -> bool { self.contains(Self::KICK_MEMBERS) }
pub fn manage_channels(self) -> bool { self.contains(Self::MANAGE_CHANNELS) }
pub fn manage_emojis(self) -> bool { self.contains(Self::MANAGE_EMOJIS) }
pub fn manage_guild(self) -> bool { self.contains(Self::MANAGE_GUILD) }
pub fn manage_messages(self) -> bool { self.contains(Self::MANAGE_MESSAGES) }
pub fn manage_nicknames(self) -> bool { self.contains(Self::MANAGE_NICKNAMES) }
pub fn manage_roles(self) -> bool { self.contains(Self::MANAGE_ROLES) }
pub fn manage_webhooks(self) -> bool { self.contains(Self::MANAGE_WEBHOOKS) }
pub fn mention_everyone(self) -> bool { self.contains(Self::MENTION_EVERYONE) }
pub fn move_members(self) -> bool { self.contains(Self::MOVE_MEMBERS) }
pub fn mute_members(self) -> bool { self.contains(Self::MUTE_MEMBERS) }
pub fn read_message_history(self) -> bool { self.contains(Self::READ_MESSAGE_HISTORY) }
pub fn read_messages(self) -> bool { self.contains(Self::READ_MESSAGES) }
pub fn send_messages(self) -> bool { self.contains(Self::SEND_MESSAGES) }
pub fn send_tts_messages(self) -> bool { self.contains(Self::SEND_TTS_MESSAGES) }
pub fn speak(self) -> bool { self.contains(Self::SPEAK) }
pub fn use_external_emojis(self) -> bool { self.contains(Self::USE_EXTERNAL_EMOJIS) }
pub fn use_vad(self) -> bool { self.contains(Self::USE_VAD) }
}
impl Default for Permissions {
fn default() -> Self { Self::empty() }
}
impl<'de> Deserialize<'de> for Permissions {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(Permissions::from_bits_truncate(
deserializer.deserialize_u64(U64Visitor)?,
))
}
}
impl Serialize for Permissions {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer {
serializer.serialize_u64(self.bits())
}
}
impl Display for Permissions {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
let names = self.get_permission_names();
let total = names.len();
for (i, &name) in names.iter().enumerate() {
if i > 0 && i != total - 1 {
write!(f, ", ")?;
}
if total > 1 && i == total - 1 {
write!(f, " and ")?;
}
write!(f, "{}", name)?;
}
Ok(())
}
}