From e0c3306e7a42fa78f5daceb948d7fca2d603e930 Mon Sep 17 00:00:00 2001 From: Zeyla Hellyer Date: Tue, 24 Jan 2023 19:40:29 -0800 Subject: [PATCH 1/5] test(model): bitflags static assertions + serde Add static assertions for bitflag implementations and constant values, as well as tests for the serde implementations. The serde tests include a test for the (de)serialization of a variant and that unknown bits are truncated on deserialization. --- twilight-model/src/channel/flags.rs | 57 +++++++++++ twilight-model/src/channel/message/flags.rs | 54 ++++++++++- twilight-model/src/gateway/intents.rs | 77 +++++++++++++++ .../src/gateway/presence/activity_flags.rs | 64 +++++++++++++ twilight-model/src/guild/permissions.rs | 96 +++++++++++++++++++ .../src/guild/system_channel_flags.rs | 78 +++++++++++++++ twilight-model/src/oauth/application_flags.rs | 73 ++++++++++++++ twilight-model/src/user/flags.rs | 74 ++++++++++++++ 8 files changed, 569 insertions(+), 4 deletions(-) diff --git a/twilight-model/src/channel/flags.rs b/twilight-model/src/channel/flags.rs index 9b5d535ab08..eeeb5ab50d4 100644 --- a/twilight-model/src/channel/flags.rs +++ b/twilight-model/src/channel/flags.rs @@ -27,3 +27,60 @@ impl Serialize for ChannelFlags { serializer.serialize_u64(self.bits()) } } + +#[cfg(test)] +mod tests { + use super::ChannelFlags; + use serde::{Deserialize, Serialize}; + use serde_test::Token; + use static_assertions::{assert_impl_all, const_assert_eq}; + use std::{ + fmt::{Binary, Debug, LowerHex, Octal, UpperHex}, + hash::Hash, + ops::{ + BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign, + }, + }; + + assert_impl_all!( + ChannelFlags: Binary, + BitAnd, + BitAndAssign, + BitOr, + BitOrAssign, + BitXor, + BitXorAssign, + Clone, + Copy, + Debug, + Deserialize<'static>, + Eq, + Extend, + FromIterator, + Hash, + LowerHex, + Not, + Octal, + Ord, + PartialEq, + PartialOrd, + Send, + Serialize, + Sub, + SubAssign, + Sync, + UpperHex + ); + const_assert_eq!(ChannelFlags::PINNED.bits(), 1 << 1); + const_assert_eq!(ChannelFlags::REQUIRE_TAG.bits(), 1 << 4); + + #[test] + fn serde() { + serde_test::assert_tokens( + &ChannelFlags::PINNED, + &[Token::U64(ChannelFlags::PINNED.bits())], + ); + // Deserialization truncates unknown bits. + serde_test::assert_de_tokens(&ChannelFlags::empty(), &[Token::U64(1 << 63)]); + } +} diff --git a/twilight-model/src/channel/message/flags.rs b/twilight-model/src/channel/message/flags.rs index f0f26a0e7ab..070f7da5bdd 100644 --- a/twilight-model/src/channel/message/flags.rs +++ b/twilight-model/src/channel/message/flags.rs @@ -53,19 +53,65 @@ impl Serialize for MessageFlags { mod tests { use super::MessageFlags; use serde::{Deserialize, Serialize}; - use static_assertions::assert_impl_all; - use std::{fmt::Debug, hash::Hash}; + use serde_test::Token; + use static_assertions::{assert_impl_all, const_assert_eq}; + use std::{ + fmt::{Binary, Debug, LowerHex, Octal, UpperHex}, + hash::Hash, + ops::{ + BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign, + }, + }; assert_impl_all!( - MessageFlags: Copy, + MessageFlags: Binary, + BitAnd, + BitAndAssign, + BitOr, + BitOrAssign, + BitXor, + BitXorAssign, Clone, + Copy, Debug, Deserialize<'static>, Eq, + Extend, + FromIterator, Hash, + LowerHex, + Not, + Octal, + Ord, PartialEq, + PartialOrd, Send, Serialize, - Sync + Sub, + SubAssign, + Sync, + UpperHex ); + const_assert_eq!(MessageFlags::CROSSPOSTED.bits(), 1); + const_assert_eq!(MessageFlags::IS_CROSSPOST.bits(), 1 << 1); + const_assert_eq!(MessageFlags::SUPPRESS_EMBEDS.bits(), 1 << 2); + const_assert_eq!(MessageFlags::SOURCE_MESSAGE_DELETED.bits(), 1 << 3); + const_assert_eq!(MessageFlags::URGENT.bits(), 1 << 4); + const_assert_eq!(MessageFlags::HAS_THREAD.bits(), 1 << 5); + const_assert_eq!(MessageFlags::EPHEMERAL.bits(), 1 << 6); + const_assert_eq!(MessageFlags::LOADING.bits(), 1 << 7); + const_assert_eq!( + MessageFlags::FAILED_TO_MENTION_SOME_ROLES_IN_THREAD.bits(), + 1 << 8 + ); + + #[test] + fn serde() { + serde_test::assert_tokens( + &MessageFlags::CROSSPOSTED, + &[Token::U64(MessageFlags::CROSSPOSTED.bits())], + ); + // Deserialization truncates unknown bits. + serde_test::assert_de_tokens(&MessageFlags::empty(), &[Token::U64(1 << 63)]); + } } diff --git a/twilight-model/src/gateway/intents.rs b/twilight-model/src/gateway/intents.rs index 23f00d2d399..5778a353661 100644 --- a/twilight-model/src/gateway/intents.rs +++ b/twilight-model/src/gateway/intents.rs @@ -288,3 +288,80 @@ impl Serialize for Intents { serializer.serialize_u64(self.bits()) } } + +#[cfg(test)] +mod tests { + #![allow(deprecated)] + + use super::Intents; + use serde::{Deserialize, Serialize}; + use serde_test::Token; + use static_assertions::{assert_impl_all, const_assert_eq}; + use std::{ + fmt::{Binary, Debug, LowerHex, Octal, UpperHex}, + hash::Hash, + ops::{ + BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign, + }, + }; + + assert_impl_all!( + Intents: Binary, + BitAnd, + BitAndAssign, + BitOr, + BitOrAssign, + BitXor, + BitXorAssign, + Clone, + Copy, + Debug, + Deserialize<'static>, + Eq, + Extend, + FromIterator, + Hash, + LowerHex, + Not, + Octal, + Ord, + PartialEq, + PartialOrd, + Send, + Serialize, + Sub, + SubAssign, + Sync, + UpperHex + ); + const_assert_eq!(Intents::GUILDS.bits(), 1); + const_assert_eq!(Intents::GUILD_MEMBERS.bits(), 1 << 1); + const_assert_eq!(Intents::GUILD_BANS.bits(), 1 << 2); + const_assert_eq!(Intents::GUILD_MODERATION.bits(), 1 << 2); + const_assert_eq!(Intents::GUILD_EMOJIS_AND_STICKERS.bits(), 1 << 3); + const_assert_eq!(Intents::GUILD_INTEGRATIONS.bits(), 1 << 4); + const_assert_eq!(Intents::GUILD_WEBHOOKS.bits(), 1 << 5); + const_assert_eq!(Intents::GUILD_INVITES.bits(), 1 << 6); + const_assert_eq!(Intents::GUILD_VOICE_STATES.bits(), 1 << 7); + const_assert_eq!(Intents::GUILD_PRESENCES.bits(), 1 << 8); + const_assert_eq!(Intents::GUILD_MESSAGES.bits(), 1 << 9); + const_assert_eq!(Intents::GUILD_MESSAGE_REACTIONS.bits(), 1 << 10); + const_assert_eq!(Intents::GUILD_MESSAGE_TYPING.bits(), 1 << 11); + const_assert_eq!(Intents::DIRECT_MESSAGES.bits(), 1 << 12); + const_assert_eq!(Intents::DIRECT_MESSAGE_REACTIONS.bits(), 1 << 13); + const_assert_eq!(Intents::DIRECT_MESSAGE_TYPING.bits(), 1 << 14); + const_assert_eq!(Intents::MESSAGE_CONTENT.bits(), 1 << 15); + const_assert_eq!(Intents::GUILD_SCHEDULED_EVENTS.bits(), 1 << 16); + const_assert_eq!(Intents::AUTO_MODERATION_CONFIGURATION.bits(), 1 << 20); + const_assert_eq!(Intents::AUTO_MODERATION_EXECUTION.bits(), 1 << 21); + + #[test] + fn serde() { + serde_test::assert_tokens( + &Intents::MESSAGE_CONTENT, + &[Token::U64(Intents::MESSAGE_CONTENT.bits())], + ); + // Deserialization truncates unknown bits. + serde_test::assert_de_tokens(&Intents::empty(), &[Token::U64(1 << 63)]); + } +} diff --git a/twilight-model/src/gateway/presence/activity_flags.rs b/twilight-model/src/gateway/presence/activity_flags.rs index b8d03d798ac..4199e67f904 100644 --- a/twilight-model/src/gateway/presence/activity_flags.rs +++ b/twilight-model/src/gateway/presence/activity_flags.rs @@ -32,3 +32,67 @@ impl Serialize for ActivityFlags { serializer.serialize_u64(self.bits()) } } + +#[cfg(test)] +mod tests { + use super::ActivityFlags; + use serde::{Deserialize, Serialize}; + use serde_test::Token; + use static_assertions::{assert_impl_all, const_assert_eq}; + use std::{ + fmt::{Binary, Debug, LowerHex, Octal, UpperHex}, + hash::Hash, + ops::{ + BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign, + }, + }; + + assert_impl_all!( + ActivityFlags: Binary, + BitAnd, + BitAndAssign, + BitOr, + BitOrAssign, + BitXor, + BitXorAssign, + Clone, + Copy, + Debug, + Deserialize<'static>, + Eq, + Extend, + FromIterator, + Hash, + LowerHex, + Not, + Octal, + Ord, + PartialEq, + PartialOrd, + Send, + Serialize, + Sub, + SubAssign, + Sync, + UpperHex + ); + const_assert_eq!(ActivityFlags::INSTANCE.bits(), 1); + const_assert_eq!(ActivityFlags::JOIN.bits(), 1 << 1); + const_assert_eq!(ActivityFlags::SPECTATE.bits(), 1 << 2); + const_assert_eq!(ActivityFlags::JOIN_REQUEST.bits(), 1 << 3); + const_assert_eq!(ActivityFlags::SYNC.bits(), 1 << 4); + const_assert_eq!(ActivityFlags::PLAY.bits(), 1 << 5); + const_assert_eq!(ActivityFlags::PARTY_PRIVACY_FRIENDS.bits(), 1 << 6); + const_assert_eq!(ActivityFlags::PARTY_PRIVACY_VOICE_CHANNEL.bits(), 1 << 7); + const_assert_eq!(ActivityFlags::EMBEDDED.bits(), 1 << 8); + + #[test] + fn serde() { + serde_test::assert_tokens( + &ActivityFlags::EMBEDDED, + &[Token::U64(ActivityFlags::EMBEDDED.bits())], + ); + // Deserialization truncates unknown bits. + serde_test::assert_de_tokens(&ActivityFlags::empty(), &[Token::U64(1 << 63)]); + } +} diff --git a/twilight-model/src/guild/permissions.rs b/twilight-model/src/guild/permissions.rs index b340bfc7b30..5268cec104b 100644 --- a/twilight-model/src/guild/permissions.rs +++ b/twilight-model/src/guild/permissions.rs @@ -102,3 +102,99 @@ impl Serialize for Permissions { serializer.serialize_str(&self.bits().to_string()) } } + +#[cfg(test)] +mod tests { + use super::Permissions; + use serde::{Deserialize, Serialize}; + use serde_test::Token; + use static_assertions::{assert_impl_all, const_assert_eq}; + use std::{ + fmt::{Binary, Debug, LowerHex, Octal, UpperHex}, + hash::Hash, + ops::{ + BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign, + }, + }; + + assert_impl_all!( + Permissions: Binary, + BitAnd, + BitAndAssign, + BitOr, + BitOrAssign, + BitXor, + BitXorAssign, + Clone, + Copy, + Debug, + Deserialize<'static>, + Eq, + Extend, + FromIterator, + Hash, + LowerHex, + Not, + Octal, + Ord, + PartialEq, + PartialOrd, + Send, + Serialize, + Sub, + SubAssign, + Sync, + UpperHex + ); + const_assert_eq!(Permissions::CREATE_INVITE.bits(), 1); + const_assert_eq!(Permissions::KICK_MEMBERS.bits(), 1 << 1); + const_assert_eq!(Permissions::BAN_MEMBERS.bits(), 1 << 2); + const_assert_eq!(Permissions::ADMINISTRATOR.bits(), 1 << 3); + const_assert_eq!(Permissions::MANAGE_CHANNELS.bits(), 1 << 4); + const_assert_eq!(Permissions::MANAGE_GUILD.bits(), 1 << 5); + const_assert_eq!(Permissions::ADD_REACTIONS.bits(), 1 << 6); + const_assert_eq!(Permissions::VIEW_AUDIT_LOG.bits(), 1 << 7); + const_assert_eq!(Permissions::PRIORITY_SPEAKER.bits(), 1 << 8); + const_assert_eq!(Permissions::STREAM.bits(), 1 << 9); + const_assert_eq!(Permissions::VIEW_CHANNEL.bits(), 1 << 10); + const_assert_eq!(Permissions::SEND_MESSAGES.bits(), 1 << 11); + const_assert_eq!(Permissions::SEND_TTS_MESSAGES.bits(), 1 << 12); + const_assert_eq!(Permissions::MANAGE_MESSAGES.bits(), 1 << 13); + const_assert_eq!(Permissions::EMBED_LINKS.bits(), 1 << 14); + const_assert_eq!(Permissions::ATTACH_FILES.bits(), 1 << 15); + const_assert_eq!(Permissions::READ_MESSAGE_HISTORY.bits(), 1 << 16); + const_assert_eq!(Permissions::MENTION_EVERYONE.bits(), 1 << 17); + const_assert_eq!(Permissions::USE_EXTERNAL_EMOJIS.bits(), 1 << 18); + const_assert_eq!(Permissions::VIEW_GUILD_INSIGHTS.bits(), 1 << 19); + const_assert_eq!(Permissions::CONNECT.bits(), 1 << 20); + const_assert_eq!(Permissions::SPEAK.bits(), 1 << 21); + const_assert_eq!(Permissions::MUTE_MEMBERS.bits(), 1 << 22); + const_assert_eq!(Permissions::DEAFEN_MEMBERS.bits(), 1 << 23); + const_assert_eq!(Permissions::MOVE_MEMBERS.bits(), 1 << 24); + const_assert_eq!(Permissions::USE_VAD.bits(), 1 << 25); + const_assert_eq!(Permissions::CHANGE_NICKNAME.bits(), 1 << 26); + const_assert_eq!(Permissions::MANAGE_NICKNAMES.bits(), 1 << 27); + const_assert_eq!(Permissions::MANAGE_ROLES.bits(), 1 << 28); + const_assert_eq!(Permissions::MANAGE_WEBHOOKS.bits(), 1 << 29); + const_assert_eq!(Permissions::MANAGE_EMOJIS_AND_STICKERS.bits(), 1 << 30); + const_assert_eq!(Permissions::USE_SLASH_COMMANDS.bits(), 1 << 31); + const_assert_eq!(Permissions::REQUEST_TO_SPEAK.bits(), 1 << 32); + const_assert_eq!(Permissions::MANAGE_EVENTS.bits(), 1 << 33); + const_assert_eq!(Permissions::MANAGE_THREADS.bits(), 1 << 34); + const_assert_eq!(Permissions::CREATE_PUBLIC_THREADS.bits(), 1 << 35); + const_assert_eq!(Permissions::CREATE_PRIVATE_THREADS.bits(), 1 << 36); + const_assert_eq!(Permissions::USE_EXTERNAL_STICKERS.bits(), 1 << 37); + const_assert_eq!(Permissions::SEND_MESSAGES_IN_THREADS.bits(), 1 << 38); + const_assert_eq!(Permissions::USE_EMBEDDED_ACTIVITIES.bits(), 1 << 39); + const_assert_eq!(Permissions::MODERATE_MEMBERS.bits(), 1 << 40); + + #[test] + fn serde() { + serde_test::assert_tokens( + &Permissions::MANAGE_ROLES, + &[Token::U64(Permissions::MANAGE_ROLES.bits())], + ); + // Deserialization truncates unknown bits. + serde_test::assert_de_tokens(&Permissions::empty(), &[Token::U64(1 << 63)]); + } +} diff --git a/twilight-model/src/guild/system_channel_flags.rs b/twilight-model/src/guild/system_channel_flags.rs index 8efd84c37ae..aba67e369b1 100644 --- a/twilight-model/src/guild/system_channel_flags.rs +++ b/twilight-model/src/guild/system_channel_flags.rs @@ -35,3 +35,81 @@ impl Serialize for SystemChannelFlags { serializer.serialize_u64(self.bits()) } } + +#[cfg(test)] +mod tests { + use super::SystemChannelFlags; + use serde::{Deserialize, Serialize}; + use serde_test::Token; + use static_assertions::{assert_impl_all, const_assert_eq}; + use std::{ + fmt::{Binary, Debug, LowerHex, Octal, UpperHex}, + hash::Hash, + ops::{ + BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign, + }, + }; + + assert_impl_all!( + SystemChannelFlags: Binary, + BitAnd, + BitAndAssign, + BitOr, + BitOrAssign, + BitXor, + BitXorAssign, + Clone, + Copy, + Debug, + Deserialize<'static>, + Eq, + Extend, + FromIterator, + Hash, + LowerHex, + Not, + Octal, + Ord, + PartialEq, + PartialOrd, + Send, + Serialize, + Sub, + SubAssign, + Sync, + UpperHex + ); + const_assert_eq!(SystemChannelFlags::SUPPRESS_JOIN_NOTIFICATIONS.bits(), 1); + const_assert_eq!( + SystemChannelFlags::SUPPRESS_PREMIUM_SUBSCRIPTIONS.bits(), + 1 << 1 + ); + const_assert_eq!( + SystemChannelFlags::SUPPRESS_GUILD_REMINDER_NOTIFICATIONS.bits(), + 1 << 2 + ); + const_assert_eq!( + SystemChannelFlags::SUPPRESS_JOIN_NOTIFICATION_REPLIES.bits(), + 1 << 3 + ); + const_assert_eq!( + SystemChannelFlags::SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATIONS.bits(), + 1 << 4 + ); + const_assert_eq!( + SystemChannelFlags::SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATION_REPLIES.bits(), + 1 << 5 + ); + + #[test] + fn serde() { + serde_test::assert_tokens( + &SystemChannelFlags::SUPPRESS_JOIN_NOTIFICATION_REPLIES, + &[Token::U64( + SystemChannelFlags::SUPPRESS_JOIN_NOTIFICATION_REPLIES.bits(), + )], + ); + // Deserialization truncates unknown bits. + serde_test::assert_de_tokens(&SystemChannelFlags::empty(), &[Token::U64(1 << 63)]); + } +} diff --git a/twilight-model/src/oauth/application_flags.rs b/twilight-model/src/oauth/application_flags.rs index 92a0b3711fa..3cbe3719d3a 100644 --- a/twilight-model/src/oauth/application_flags.rs +++ b/twilight-model/src/oauth/application_flags.rs @@ -62,3 +62,76 @@ impl Serialize for ApplicationFlags { serializer.serialize_u64(self.bits()) } } + +#[cfg(test)] +mod tests { + use super::ApplicationFlags; + use serde::{Deserialize, Serialize}; + use serde_test::Token; + use static_assertions::{assert_impl_all, const_assert_eq}; + use std::{ + fmt::{Binary, Debug, LowerHex, Octal, UpperHex}, + hash::Hash, + ops::{ + BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign, + }, + }; + + assert_impl_all!( + ApplicationFlags: Binary, + BitAnd, + BitAndAssign, + BitOr, + BitOrAssign, + BitXor, + BitXorAssign, + Clone, + Copy, + Debug, + Deserialize<'static>, + Eq, + Extend, + FromIterator, + Hash, + LowerHex, + Not, + Octal, + Ord, + PartialEq, + PartialOrd, + Send, + Serialize, + Sub, + SubAssign, + Sync, + UpperHex + ); + const_assert_eq!(ApplicationFlags::GATEWAY_PRESENCE.bits(), 1 << 12); + const_assert_eq!(ApplicationFlags::GATEWAY_PRESENCE_LIMITED.bits(), 1 << 13); + const_assert_eq!(ApplicationFlags::GATEWAY_GUILD_MEMBERS.bits(), 1 << 14); + const_assert_eq!( + ApplicationFlags::GATEWAY_GUILD_MEMBERS_LIMITED.bits(), + 1 << 15 + ); + const_assert_eq!( + ApplicationFlags::VERIFICATION_PENDING_GUILD_LIMIT.bits(), + 1 << 16 + ); + const_assert_eq!(ApplicationFlags::EMBEDDED.bits(), 1 << 17); + const_assert_eq!(ApplicationFlags::GATEWAY_MESSAGE_CONTENT.bits(), 1 << 18); + const_assert_eq!( + ApplicationFlags::GATEWAY_MESSAGE_CONTENT_LIMITED.bits(), + 1 << 19 + ); + const_assert_eq!(ApplicationFlags::APPLICATION_COMMAND_BADGE.bits(), 1 << 23); + + #[test] + fn serde() { + serde_test::assert_tokens( + &ApplicationFlags::GATEWAY_MESSAGE_CONTENT, + &[Token::U64(ApplicationFlags::GATEWAY_MESSAGE_CONTENT.bits())], + ); + // Deserialization truncates unknown bits. + serde_test::assert_de_tokens(&ApplicationFlags::empty(), &[Token::U64(1 << 63)]); + } +} diff --git a/twilight-model/src/user/flags.rs b/twilight-model/src/user/flags.rs index 07ae9425aa1..fc48f191d85 100644 --- a/twilight-model/src/user/flags.rs +++ b/twilight-model/src/user/flags.rs @@ -59,3 +59,77 @@ impl Serialize for UserFlags { serializer.serialize_u64(self.bits()) } } + +#[cfg(test)] +mod tests { + #![allow(deprecated)] + + use super::UserFlags; + use serde::{Deserialize, Serialize}; + use serde_test::Token; + use static_assertions::{assert_impl_all, const_assert_eq}; + use std::{ + fmt::{Binary, Debug, LowerHex, Octal, UpperHex}, + hash::Hash, + ops::{ + BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign, + }, + }; + + assert_impl_all!( + UserFlags: Binary, + BitAnd, + BitAndAssign, + BitOr, + BitOrAssign, + BitXor, + BitXorAssign, + Clone, + Copy, + Debug, + Deserialize<'static>, + Eq, + Extend, + FromIterator, + Hash, + LowerHex, + Not, + Octal, + Ord, + PartialEq, + PartialOrd, + Send, + Serialize, + Sub, + SubAssign, + Sync, + UpperHex + ); + + const_assert_eq!(UserFlags::STAFF.bits(), 1); + const_assert_eq!(UserFlags::PARTNER.bits(), 1 << 1); + const_assert_eq!(UserFlags::HYPESQUAD.bits(), 1 << 2); + const_assert_eq!(UserFlags::BUG_HUNTER_LEVEL_1.bits(), 1 << 3); + const_assert_eq!(UserFlags::HYPESQUAD_ONLINE_HOUSE_1.bits(), 1 << 6); + const_assert_eq!(UserFlags::HYPESQUAD_ONLINE_HOUSE_2.bits(), 1 << 7); + const_assert_eq!(UserFlags::HYPESQUAD_ONLINE_HOUSE_3.bits(), 1 << 8); + const_assert_eq!(UserFlags::PREMIUM_EARLY_SUPPORTER.bits(), 1 << 9); + const_assert_eq!(UserFlags::TEAM_PSEUDO_USER.bits(), 1 << 10); + const_assert_eq!(UserFlags::BUG_HUNTER_LEVEL_2.bits(), 1 << 14); + const_assert_eq!(UserFlags::VERIFIED_BOT.bits(), 1 << 16); + const_assert_eq!(UserFlags::VERIFIED_DEVELOPER.bits(), 1 << 17); + const_assert_eq!(UserFlags::CERTIFIED_MODERATOR.bits(), 1 << 18); + const_assert_eq!(UserFlags::MODERATOR_PROGRAMS_ALUMNI.bits(), 1 << 18); + const_assert_eq!(UserFlags::BOT_HTTP_INTERACTIONS.bits(), 1 << 19); + const_assert_eq!(UserFlags::ACTIVE_DEVELOPER.bits(), 1 << 22); + + #[test] + fn serde() { + serde_test::assert_tokens( + &UserFlags::PARTNER, + &[Token::U64(UserFlags::PARTNER.bits())], + ); + // Deserialization truncates unknown bits. + serde_test::assert_de_tokens(&UserFlags::empty(), &[Token::U64(1 << 63)]); + } +} From a5908bd767ce8d28faf07e3b51b514b40b66e94e Mon Sep 17 00:00:00 2001 From: Zeyla Hellyer Date: Tue, 24 Jan 2023 20:06:33 -0800 Subject: [PATCH 2/5] fix --- twilight-model/src/guild/permissions.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/twilight-model/src/guild/permissions.rs b/twilight-model/src/guild/permissions.rs index 5268cec104b..39b383da147 100644 --- a/twilight-model/src/guild/permissions.rs +++ b/twilight-model/src/guild/permissions.rs @@ -190,11 +190,8 @@ mod tests { #[test] fn serde() { - serde_test::assert_tokens( - &Permissions::MANAGE_ROLES, - &[Token::U64(Permissions::MANAGE_ROLES.bits())], - ); + serde_test::assert_tokens(&Permissions::CREATE_INVITE, &[Token::Str("1")]); // Deserialization truncates unknown bits. - serde_test::assert_de_tokens(&Permissions::empty(), &[Token::U64(1 << 63)]); + serde_test::assert_de_tokens(&Permissions::empty(), &[Token::Str("9223372036854775808")]); } } From 071b7ae97c9ea85431178d64233f8e93441961cc Mon Sep 17 00:00:00 2001 From: Zeyla Hellyer Date: Tue, 24 Jan 2023 20:06:54 -0800 Subject: [PATCH 3/5] feat(model)!: don't truncate bitflags Bitflags received from the Discord API are truncated when deserialized. However, we have recently taken a model of accepting "unknown information", with our recent reworks of enums the shining example. Instead of failing to deserialize / ignore "unknown variants" we have taken the step to treat unknown data as "first class", in that Twilight not necessarily registering known values is okay and users can manually handle variants as they need. We should apply the same logic to bitflags and not trim unknown data. This unfortunately makes use of unsafe code for constructing bitflags in tests, because `bitflags` has an unorthodox definition of what "unsafe" is for its `Bitflags::from_bits_unchecked` function. `bitflags` treats unknown bits as being "unsafe", and so the function to construct bitflags with possibly unknown variants is unsafe. I have added notes detailing this. This is a breaking change because unknown bits are no longer truncated. Blocks on PR #2088. --- twilight-model/src/channel/flags.rs | 36 ++++++++----------- twilight-model/src/channel/message/flags.rs | 36 ++++++++----------- .../src/gateway/presence/activity_flags.rs | 31 ++++++---------- twilight-model/src/guild/permissions.rs | 32 ++++++++++++++--- .../src/guild/system_channel_flags.rs | 36 ++++++++----------- twilight-model/src/oauth/application_flags.rs | 36 ++++++++----------- twilight-model/src/user/flags.rs | 36 ++++++++----------- 7 files changed, 112 insertions(+), 131 deletions(-) diff --git a/twilight-model/src/channel/flags.rs b/twilight-model/src/channel/flags.rs index eeeb5ab50d4..a642ab54b65 100644 --- a/twilight-model/src/channel/flags.rs +++ b/twilight-model/src/channel/flags.rs @@ -1,10 +1,10 @@ use bitflags::bitflags; -use serde::{ - de::{Deserialize, Deserializer}, - ser::{Serialize, Serializer}, -}; +use serde::{Deserialize, Serialize}; bitflags! { + #[allow(clippy::unsafe_derive_deserialize)] + #[derive(Deserialize, Serialize)] + #[serde(transparent)] pub struct ChannelFlags: u64 { /// Channel is pinned in a forum. const PINNED = 1 << 1; @@ -13,21 +13,6 @@ bitflags! { } } -impl<'de> Deserialize<'de> for ChannelFlags { - fn deserialize>(deserializer: D) -> Result { - Ok(Self::from_bits_truncate(u64::deserialize(deserializer)?)) - } -} - -impl Serialize for ChannelFlags { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_u64(self.bits()) - } -} - #[cfg(test)] mod tests { use super::ChannelFlags; @@ -80,7 +65,16 @@ mod tests { &ChannelFlags::PINNED, &[Token::U64(ChannelFlags::PINNED.bits())], ); - // Deserialization truncates unknown bits. - serde_test::assert_de_tokens(&ChannelFlags::empty(), &[Token::U64(1 << 63)]); + // Safety: + // + // Deserialization doesn't truncate unknown bits. + // + // `bitflags` requires unsafe code to create bitflags with unknown bits + // due to an unorthodox definition of unsafe: + // + // + #[allow(unsafe_code)] + let value = unsafe { ChannelFlags::from_bits_unchecked(1 << 63) }; + serde_test::assert_de_tokens(&value, &[Token::U64(1 << 63)]); } } diff --git a/twilight-model/src/channel/message/flags.rs b/twilight-model/src/channel/message/flags.rs index 070f7da5bdd..d734c6e1598 100644 --- a/twilight-model/src/channel/message/flags.rs +++ b/twilight-model/src/channel/message/flags.rs @@ -1,11 +1,11 @@ use bitflags::bitflags; -use serde::{ - de::{Deserialize, Deserializer}, - ser::{Serialize, Serializer}, -}; +use serde::{Deserialize, Serialize}; bitflags! { /// Flags to signal state and modify the look of a message. + #[allow(clippy::unsafe_derive_deserialize)] + #[derive(Deserialize, Serialize)] + #[serde(transparent)] pub struct MessageFlags: u64 { /// Has been published to subscribed channels via Channel Following. const CROSSPOSTED = 1; @@ -34,21 +34,6 @@ bitflags! { } } -impl<'de> Deserialize<'de> for MessageFlags { - fn deserialize>(deserializer: D) -> Result { - Ok(Self::from_bits_truncate(u64::deserialize(deserializer)?)) - } -} - -impl Serialize for MessageFlags { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_u64(self.bits()) - } -} - #[cfg(test)] mod tests { use super::MessageFlags; @@ -111,7 +96,16 @@ mod tests { &MessageFlags::CROSSPOSTED, &[Token::U64(MessageFlags::CROSSPOSTED.bits())], ); - // Deserialization truncates unknown bits. - serde_test::assert_de_tokens(&MessageFlags::empty(), &[Token::U64(1 << 63)]); + // Safety: + // + // Deserialization doesn't truncate unknown bits. + // + // `bitflags` requires unsafe code to create bitflags with unknown bits + // due to an unorthodox definition of unsafe: + // + // + #[allow(unsafe_code)] + let value = unsafe { MessageFlags::from_bits_unchecked(1 << 63) }; + serde_test::assert_de_tokens(&value, &[Token::U64(1 << 63)]); } } diff --git a/twilight-model/src/gateway/presence/activity_flags.rs b/twilight-model/src/gateway/presence/activity_flags.rs index 4199e67f904..4d705dcd838 100644 --- a/twilight-model/src/gateway/presence/activity_flags.rs +++ b/twilight-model/src/gateway/presence/activity_flags.rs @@ -1,10 +1,10 @@ use bitflags::bitflags; -use serde::{ - de::{Deserialize, Deserializer}, - ser::{Serialize, Serializer}, -}; +use serde::{Deserialize, Serialize}; bitflags! { + #[allow(clippy::unsafe_derive_deserialize)] + #[derive(Deserialize, Serialize)] + #[serde(transparent)] pub struct ActivityFlags: u64 { const INSTANCE = 1; const JOIN = 1 << 1; @@ -18,21 +18,6 @@ bitflags! { } } -impl<'de> Deserialize<'de> for ActivityFlags { - fn deserialize>(deserializer: D) -> Result { - Ok(Self::from_bits_truncate(u64::deserialize(deserializer)?)) - } -} - -impl Serialize for ActivityFlags { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_u64(self.bits()) - } -} - #[cfg(test)] mod tests { use super::ActivityFlags; @@ -92,7 +77,11 @@ mod tests { &ActivityFlags::EMBEDDED, &[Token::U64(ActivityFlags::EMBEDDED.bits())], ); - // Deserialization truncates unknown bits. - serde_test::assert_de_tokens(&ActivityFlags::empty(), &[Token::U64(1 << 63)]); + // Deserialization doesn't truncate unknown bits. + // + // `bitflags` requires unsafe code to create bitflags with unknown bits. + #[allow(unsafe_code)] + let value = unsafe { ActivityFlags::from_bits_unchecked(1 << 63) }; + serde_test::assert_de_tokens(&value, &[Token::U64(1 << 63)]); } } diff --git a/twilight-model/src/guild/permissions.rs b/twilight-model/src/guild/permissions.rs index 39b383da147..e19b2c295c4 100644 --- a/twilight-model/src/guild/permissions.rs +++ b/twilight-model/src/guild/permissions.rs @@ -1,7 +1,8 @@ use bitflags::bitflags; use serde::{ - de::{Deserialize, Deserializer, Error as DeError, Visitor}, - ser::{Serialize, Serializer}, + de::{Deserializer, Error as DeError, Visitor}, + ser::Serializer, + Deserialize, Serialize, }; use std::fmt::{Formatter, Result as FmtResult}; @@ -78,7 +79,19 @@ impl<'de> Visitor<'de> for PermissionsVisitor { } fn visit_u64(self, v: u64) -> Result { - Ok(Permissions::from_bits_truncate(v)) + // Safety: + // + // `bitflags` requires unsafe code to create bitflags with unknown bits + // due to an unorthodox definition of unsafe: + // + // + // + // This is, funnily enough, how bitflags itself implements + // deserializers. + #[allow(unsafe_code)] + let permissions = unsafe { Permissions::from_bits_unchecked(v) }; + + Ok(permissions) } fn visit_str(self, v: &str) -> Result { @@ -191,7 +204,16 @@ mod tests { #[test] fn serde() { serde_test::assert_tokens(&Permissions::CREATE_INVITE, &[Token::Str("1")]); - // Deserialization truncates unknown bits. - serde_test::assert_de_tokens(&Permissions::empty(), &[Token::Str("9223372036854775808")]); + // Safety: + // + // Deserialization doesn't truncate unknown bits. + // + // `bitflags` requires unsafe code to create bitflags with unknown bits + // due to an unorthodox definition of unsafe: + // + // + #[allow(unsafe_code)] + let value = unsafe { Permissions::from_bits_unchecked(1 << 63) }; + serde_test::assert_de_tokens(&value, &[Token::Str("9223372036854775808")]); } } diff --git a/twilight-model/src/guild/system_channel_flags.rs b/twilight-model/src/guild/system_channel_flags.rs index aba67e369b1..068a8dc0fa5 100644 --- a/twilight-model/src/guild/system_channel_flags.rs +++ b/twilight-model/src/guild/system_channel_flags.rs @@ -1,10 +1,10 @@ use bitflags::bitflags; -use serde::{ - de::{Deserialize, Deserializer}, - ser::{Serialize, Serializer}, -}; +use serde::{Deserialize, Serialize}; bitflags! { + #[allow(clippy::unsafe_derive_deserialize)] + #[derive(Deserialize, Serialize)] + #[serde(transparent)] pub struct SystemChannelFlags: u64 { /// Suppress member join notifications. const SUPPRESS_JOIN_NOTIFICATIONS = 1; @@ -21,21 +21,6 @@ bitflags! { } } -impl<'de> Deserialize<'de> for SystemChannelFlags { - fn deserialize>(deserializer: D) -> Result { - Ok(Self::from_bits_truncate(u64::deserialize(deserializer)?)) - } -} - -impl Serialize for SystemChannelFlags { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_u64(self.bits()) - } -} - #[cfg(test)] mod tests { use super::SystemChannelFlags; @@ -109,7 +94,16 @@ mod tests { SystemChannelFlags::SUPPRESS_JOIN_NOTIFICATION_REPLIES.bits(), )], ); - // Deserialization truncates unknown bits. - serde_test::assert_de_tokens(&SystemChannelFlags::empty(), &[Token::U64(1 << 63)]); + // Safety: + // + // Deserialization doesn't truncate unknown bits. + // + // `bitflags` requires unsafe code to create bitflags with unknown bits + // due to an unorthodox definition of unsafe: + // + // + #[allow(unsafe_code)] + let value = unsafe { SystemChannelFlags::from_bits_unchecked(1 << 63) }; + serde_test::assert_de_tokens(&value, &[Token::U64(1 << 63)]); } } diff --git a/twilight-model/src/oauth/application_flags.rs b/twilight-model/src/oauth/application_flags.rs index 3cbe3719d3a..08a3bdcee76 100644 --- a/twilight-model/src/oauth/application_flags.rs +++ b/twilight-model/src/oauth/application_flags.rs @@ -1,10 +1,10 @@ use bitflags::bitflags; -use serde::{ - de::{Deserialize, Deserializer}, - ser::{Serialize, Serializer}, -}; +use serde::{Deserialize, Serialize}; bitflags! { + #[allow(clippy::unsafe_derive_deserialize)] + #[derive(Deserialize, Serialize)] + #[serde(transparent)] pub struct ApplicationFlags: u64 { /// Intent required for bots in 100 guilds or more to receive /// [`PresenceUpdate`] events. @@ -48,21 +48,6 @@ bitflags! { } } -impl<'de> Deserialize<'de> for ApplicationFlags { - fn deserialize>(deserializer: D) -> Result { - Ok(Self::from_bits_truncate(u64::deserialize(deserializer)?)) - } -} - -impl Serialize for ApplicationFlags { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_u64(self.bits()) - } -} - #[cfg(test)] mod tests { use super::ApplicationFlags; @@ -131,7 +116,16 @@ mod tests { &ApplicationFlags::GATEWAY_MESSAGE_CONTENT, &[Token::U64(ApplicationFlags::GATEWAY_MESSAGE_CONTENT.bits())], ); - // Deserialization truncates unknown bits. - serde_test::assert_de_tokens(&ApplicationFlags::empty(), &[Token::U64(1 << 63)]); + // Safety: + // + // Deserialization doesn't truncate unknown bits. + // + // `bitflags` requires unsafe code to create bitflags with unknown bits + // due to an unorthodox definition of unsafe: + // + // + #[allow(unsafe_code)] + let value = unsafe { ApplicationFlags::from_bits_unchecked(1 << 63) }; + serde_test::assert_de_tokens(&value, &[Token::U64(1 << 63)]); } } diff --git a/twilight-model/src/user/flags.rs b/twilight-model/src/user/flags.rs index fc48f191d85..e49a71a6b43 100644 --- a/twilight-model/src/user/flags.rs +++ b/twilight-model/src/user/flags.rs @@ -1,10 +1,10 @@ use bitflags::bitflags; -use serde::{ - de::{Deserialize, Deserializer}, - ser::{Serialize, Serializer}, -}; +use serde::{Deserialize, Serialize}; bitflags! { + #[allow(clippy::unsafe_derive_deserialize)] + #[derive(Deserialize, Serialize)] + #[serde(transparent)] pub struct UserFlags: u64 { /// Discord Employee. const STAFF = 1; @@ -45,21 +45,6 @@ bitflags! { } } -impl<'de> Deserialize<'de> for UserFlags { - fn deserialize>(deserializer: D) -> Result { - Ok(Self::from_bits_truncate(u64::deserialize(deserializer)?)) - } -} - -impl Serialize for UserFlags { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_u64(self.bits()) - } -} - #[cfg(test)] mod tests { #![allow(deprecated)] @@ -129,7 +114,16 @@ mod tests { &UserFlags::PARTNER, &[Token::U64(UserFlags::PARTNER.bits())], ); - // Deserialization truncates unknown bits. - serde_test::assert_de_tokens(&UserFlags::empty(), &[Token::U64(1 << 63)]); + // Safety: + // + // Deserialization doesn't truncate unknown bits. + // + // `bitflags` requires unsafe code to create bitflags with unknown bits + // due to an unorthodox definition of unsafe: + // + // + #[allow(unsafe_code)] + let value = unsafe { UserFlags::from_bits_unchecked(1 << 63) }; + serde_test::assert_de_tokens(&value, &[Token::U64(1 << 63)]); } } From 208b556a1d19a2f4f78d394d6cb50348f2f38c82 Mon Sep 17 00:00:00 2001 From: Zeyla Date: Sat, 28 Jan 2023 14:19:47 -0500 Subject: [PATCH 4/5] Update twilight-model/src/gateway/presence/activity_flags.rs Co-authored-by: Erk --- twilight-model/src/gateway/presence/activity_flags.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/twilight-model/src/gateway/presence/activity_flags.rs b/twilight-model/src/gateway/presence/activity_flags.rs index 4d705dcd838..b6e84091693 100644 --- a/twilight-model/src/gateway/presence/activity_flags.rs +++ b/twilight-model/src/gateway/presence/activity_flags.rs @@ -77,9 +77,14 @@ mod tests { &ActivityFlags::EMBEDDED, &[Token::U64(ActivityFlags::EMBEDDED.bits())], ); + // Safety: + // // Deserialization doesn't truncate unknown bits. // - // `bitflags` requires unsafe code to create bitflags with unknown bits. + // `bitflags` requires unsafe code to create bitflags with unknown bits + // due to an unorthodox definition of unsafe: + // + // #[allow(unsafe_code)] let value = unsafe { ActivityFlags::from_bits_unchecked(1 << 63) }; serde_test::assert_de_tokens(&value, &[Token::U64(1 << 63)]); From a9d4c46f8e37afc37e11e6db172fd49fdff6183b Mon Sep 17 00:00:00 2001 From: Cassandra McCarthy Date: Sat, 4 Feb 2023 20:25:03 -0500 Subject: [PATCH 5/5] uh --- twilight-model/src/channel/flags.rs | 57 -------------- .../src/gateway/presence/activity_flags.rs | 64 --------------- .../src/guild/system_channel_flags.rs | 78 ------------------- twilight-model/src/oauth/application_flags.rs | 73 ----------------- twilight-model/src/user/flags.rs | 74 ------------------ 5 files changed, 346 deletions(-) diff --git a/twilight-model/src/channel/flags.rs b/twilight-model/src/channel/flags.rs index f97ed1f8e5a..a642ab54b65 100644 --- a/twilight-model/src/channel/flags.rs +++ b/twilight-model/src/channel/flags.rs @@ -78,60 +78,3 @@ mod tests { serde_test::assert_de_tokens(&value, &[Token::U64(1 << 63)]); } } - -#[cfg(test)] -mod tests { - use super::ChannelFlags; - use serde::{Deserialize, Serialize}; - use serde_test::Token; - use static_assertions::{assert_impl_all, const_assert_eq}; - use std::{ - fmt::{Binary, Debug, LowerHex, Octal, UpperHex}, - hash::Hash, - ops::{ - BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign, - }, - }; - - assert_impl_all!( - ChannelFlags: Binary, - BitAnd, - BitAndAssign, - BitOr, - BitOrAssign, - BitXor, - BitXorAssign, - Clone, - Copy, - Debug, - Deserialize<'static>, - Eq, - Extend, - FromIterator, - Hash, - LowerHex, - Not, - Octal, - Ord, - PartialEq, - PartialOrd, - Send, - Serialize, - Sub, - SubAssign, - Sync, - UpperHex - ); - const_assert_eq!(ChannelFlags::PINNED.bits(), 1 << 1); - const_assert_eq!(ChannelFlags::REQUIRE_TAG.bits(), 1 << 4); - - #[test] - fn serde() { - serde_test::assert_tokens( - &ChannelFlags::PINNED, - &[Token::U64(ChannelFlags::PINNED.bits())], - ); - // Deserialization truncates unknown bits. - serde_test::assert_de_tokens(&ChannelFlags::empty(), &[Token::U64(1 << 63)]); - } -} diff --git a/twilight-model/src/gateway/presence/activity_flags.rs b/twilight-model/src/gateway/presence/activity_flags.rs index 1f7d17f9340..b6e84091693 100644 --- a/twilight-model/src/gateway/presence/activity_flags.rs +++ b/twilight-model/src/gateway/presence/activity_flags.rs @@ -90,67 +90,3 @@ mod tests { serde_test::assert_de_tokens(&value, &[Token::U64(1 << 63)]); } } - -#[cfg(test)] -mod tests { - use super::ActivityFlags; - use serde::{Deserialize, Serialize}; - use serde_test::Token; - use static_assertions::{assert_impl_all, const_assert_eq}; - use std::{ - fmt::{Binary, Debug, LowerHex, Octal, UpperHex}, - hash::Hash, - ops::{ - BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign, - }, - }; - - assert_impl_all!( - ActivityFlags: Binary, - BitAnd, - BitAndAssign, - BitOr, - BitOrAssign, - BitXor, - BitXorAssign, - Clone, - Copy, - Debug, - Deserialize<'static>, - Eq, - Extend, - FromIterator, - Hash, - LowerHex, - Not, - Octal, - Ord, - PartialEq, - PartialOrd, - Send, - Serialize, - Sub, - SubAssign, - Sync, - UpperHex - ); - const_assert_eq!(ActivityFlags::INSTANCE.bits(), 1); - const_assert_eq!(ActivityFlags::JOIN.bits(), 1 << 1); - const_assert_eq!(ActivityFlags::SPECTATE.bits(), 1 << 2); - const_assert_eq!(ActivityFlags::JOIN_REQUEST.bits(), 1 << 3); - const_assert_eq!(ActivityFlags::SYNC.bits(), 1 << 4); - const_assert_eq!(ActivityFlags::PLAY.bits(), 1 << 5); - const_assert_eq!(ActivityFlags::PARTY_PRIVACY_FRIENDS.bits(), 1 << 6); - const_assert_eq!(ActivityFlags::PARTY_PRIVACY_VOICE_CHANNEL.bits(), 1 << 7); - const_assert_eq!(ActivityFlags::EMBEDDED.bits(), 1 << 8); - - #[test] - fn serde() { - serde_test::assert_tokens( - &ActivityFlags::EMBEDDED, - &[Token::U64(ActivityFlags::EMBEDDED.bits())], - ); - // Deserialization truncates unknown bits. - serde_test::assert_de_tokens(&ActivityFlags::empty(), &[Token::U64(1 << 63)]); - } -} diff --git a/twilight-model/src/guild/system_channel_flags.rs b/twilight-model/src/guild/system_channel_flags.rs index a5d0b4e82f5..068a8dc0fa5 100644 --- a/twilight-model/src/guild/system_channel_flags.rs +++ b/twilight-model/src/guild/system_channel_flags.rs @@ -107,81 +107,3 @@ mod tests { serde_test::assert_de_tokens(&value, &[Token::U64(1 << 63)]); } } - -#[cfg(test)] -mod tests { - use super::SystemChannelFlags; - use serde::{Deserialize, Serialize}; - use serde_test::Token; - use static_assertions::{assert_impl_all, const_assert_eq}; - use std::{ - fmt::{Binary, Debug, LowerHex, Octal, UpperHex}, - hash::Hash, - ops::{ - BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign, - }, - }; - - assert_impl_all!( - SystemChannelFlags: Binary, - BitAnd, - BitAndAssign, - BitOr, - BitOrAssign, - BitXor, - BitXorAssign, - Clone, - Copy, - Debug, - Deserialize<'static>, - Eq, - Extend, - FromIterator, - Hash, - LowerHex, - Not, - Octal, - Ord, - PartialEq, - PartialOrd, - Send, - Serialize, - Sub, - SubAssign, - Sync, - UpperHex - ); - const_assert_eq!(SystemChannelFlags::SUPPRESS_JOIN_NOTIFICATIONS.bits(), 1); - const_assert_eq!( - SystemChannelFlags::SUPPRESS_PREMIUM_SUBSCRIPTIONS.bits(), - 1 << 1 - ); - const_assert_eq!( - SystemChannelFlags::SUPPRESS_GUILD_REMINDER_NOTIFICATIONS.bits(), - 1 << 2 - ); - const_assert_eq!( - SystemChannelFlags::SUPPRESS_JOIN_NOTIFICATION_REPLIES.bits(), - 1 << 3 - ); - const_assert_eq!( - SystemChannelFlags::SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATIONS.bits(), - 1 << 4 - ); - const_assert_eq!( - SystemChannelFlags::SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATION_REPLIES.bits(), - 1 << 5 - ); - - #[test] - fn serde() { - serde_test::assert_tokens( - &SystemChannelFlags::SUPPRESS_JOIN_NOTIFICATION_REPLIES, - &[Token::U64( - SystemChannelFlags::SUPPRESS_JOIN_NOTIFICATION_REPLIES.bits(), - )], - ); - // Deserialization truncates unknown bits. - serde_test::assert_de_tokens(&SystemChannelFlags::empty(), &[Token::U64(1 << 63)]); - } -} diff --git a/twilight-model/src/oauth/application_flags.rs b/twilight-model/src/oauth/application_flags.rs index eca8fdbad16..08a3bdcee76 100644 --- a/twilight-model/src/oauth/application_flags.rs +++ b/twilight-model/src/oauth/application_flags.rs @@ -129,76 +129,3 @@ mod tests { serde_test::assert_de_tokens(&value, &[Token::U64(1 << 63)]); } } - -#[cfg(test)] -mod tests { - use super::ApplicationFlags; - use serde::{Deserialize, Serialize}; - use serde_test::Token; - use static_assertions::{assert_impl_all, const_assert_eq}; - use std::{ - fmt::{Binary, Debug, LowerHex, Octal, UpperHex}, - hash::Hash, - ops::{ - BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign, - }, - }; - - assert_impl_all!( - ApplicationFlags: Binary, - BitAnd, - BitAndAssign, - BitOr, - BitOrAssign, - BitXor, - BitXorAssign, - Clone, - Copy, - Debug, - Deserialize<'static>, - Eq, - Extend, - FromIterator, - Hash, - LowerHex, - Not, - Octal, - Ord, - PartialEq, - PartialOrd, - Send, - Serialize, - Sub, - SubAssign, - Sync, - UpperHex - ); - const_assert_eq!(ApplicationFlags::GATEWAY_PRESENCE.bits(), 1 << 12); - const_assert_eq!(ApplicationFlags::GATEWAY_PRESENCE_LIMITED.bits(), 1 << 13); - const_assert_eq!(ApplicationFlags::GATEWAY_GUILD_MEMBERS.bits(), 1 << 14); - const_assert_eq!( - ApplicationFlags::GATEWAY_GUILD_MEMBERS_LIMITED.bits(), - 1 << 15 - ); - const_assert_eq!( - ApplicationFlags::VERIFICATION_PENDING_GUILD_LIMIT.bits(), - 1 << 16 - ); - const_assert_eq!(ApplicationFlags::EMBEDDED.bits(), 1 << 17); - const_assert_eq!(ApplicationFlags::GATEWAY_MESSAGE_CONTENT.bits(), 1 << 18); - const_assert_eq!( - ApplicationFlags::GATEWAY_MESSAGE_CONTENT_LIMITED.bits(), - 1 << 19 - ); - const_assert_eq!(ApplicationFlags::APPLICATION_COMMAND_BADGE.bits(), 1 << 23); - - #[test] - fn serde() { - serde_test::assert_tokens( - &ApplicationFlags::GATEWAY_MESSAGE_CONTENT, - &[Token::U64(ApplicationFlags::GATEWAY_MESSAGE_CONTENT.bits())], - ); - // Deserialization truncates unknown bits. - serde_test::assert_de_tokens(&ApplicationFlags::empty(), &[Token::U64(1 << 63)]); - } -} diff --git a/twilight-model/src/user/flags.rs b/twilight-model/src/user/flags.rs index 28b4c5d4d3d..e49a71a6b43 100644 --- a/twilight-model/src/user/flags.rs +++ b/twilight-model/src/user/flags.rs @@ -127,77 +127,3 @@ mod tests { serde_test::assert_de_tokens(&value, &[Token::U64(1 << 63)]); } } - -#[cfg(test)] -mod tests { - #![allow(deprecated)] - - use super::UserFlags; - use serde::{Deserialize, Serialize}; - use serde_test::Token; - use static_assertions::{assert_impl_all, const_assert_eq}; - use std::{ - fmt::{Binary, Debug, LowerHex, Octal, UpperHex}, - hash::Hash, - ops::{ - BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign, - }, - }; - - assert_impl_all!( - UserFlags: Binary, - BitAnd, - BitAndAssign, - BitOr, - BitOrAssign, - BitXor, - BitXorAssign, - Clone, - Copy, - Debug, - Deserialize<'static>, - Eq, - Extend, - FromIterator, - Hash, - LowerHex, - Not, - Octal, - Ord, - PartialEq, - PartialOrd, - Send, - Serialize, - Sub, - SubAssign, - Sync, - UpperHex - ); - - const_assert_eq!(UserFlags::STAFF.bits(), 1); - const_assert_eq!(UserFlags::PARTNER.bits(), 1 << 1); - const_assert_eq!(UserFlags::HYPESQUAD.bits(), 1 << 2); - const_assert_eq!(UserFlags::BUG_HUNTER_LEVEL_1.bits(), 1 << 3); - const_assert_eq!(UserFlags::HYPESQUAD_ONLINE_HOUSE_1.bits(), 1 << 6); - const_assert_eq!(UserFlags::HYPESQUAD_ONLINE_HOUSE_2.bits(), 1 << 7); - const_assert_eq!(UserFlags::HYPESQUAD_ONLINE_HOUSE_3.bits(), 1 << 8); - const_assert_eq!(UserFlags::PREMIUM_EARLY_SUPPORTER.bits(), 1 << 9); - const_assert_eq!(UserFlags::TEAM_PSEUDO_USER.bits(), 1 << 10); - const_assert_eq!(UserFlags::BUG_HUNTER_LEVEL_2.bits(), 1 << 14); - const_assert_eq!(UserFlags::VERIFIED_BOT.bits(), 1 << 16); - const_assert_eq!(UserFlags::VERIFIED_DEVELOPER.bits(), 1 << 17); - const_assert_eq!(UserFlags::CERTIFIED_MODERATOR.bits(), 1 << 18); - const_assert_eq!(UserFlags::MODERATOR_PROGRAMS_ALUMNI.bits(), 1 << 18); - const_assert_eq!(UserFlags::BOT_HTTP_INTERACTIONS.bits(), 1 << 19); - const_assert_eq!(UserFlags::ACTIVE_DEVELOPER.bits(), 1 << 22); - - #[test] - fn serde() { - serde_test::assert_tokens( - &UserFlags::PARTNER, - &[Token::U64(UserFlags::PARTNER.bits())], - ); - // Deserialization truncates unknown bits. - serde_test::assert_de_tokens(&UserFlags::empty(), &[Token::U64(1 << 63)]); - } -}