Skip to content

Commit

Permalink
Introduce internal bitflags! macro with serde implementation (#1684)
Browse files Browse the repository at this point in the history
The macro forwards the generation to the `bitflags::bitflags!` macro and
implements the default (de)serialization for Discord's bitmask values.

If a different serde implementation is required then the `bitflags::bitflags!`
macro must be used directly. See `Permissions`.
  • Loading branch information
nickelc authored and arqunis committed Mar 15, 2022
1 parent fbba88c commit 4d5f4f1
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 37 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -16,7 +16,7 @@ include = ["src/**/*", "LICENSE.md", "README.md", "CHANGELOG.md", "build.rs"]
members = ["examples/*"]

[dependencies]
bitflags = "1.1"
bitflags = "1.3"
serde_json = "1.0.75"
async-trait = "0.1.9"

Expand Down
54 changes: 41 additions & 13 deletions src/internal/macros.rs
Expand Up @@ -97,24 +97,52 @@ macro_rules! enum_number {
}
}

macro_rules! impl_bitflags_serde {
($name:ident: $type:tt) => {
impl<'de> serde::de::Deserialize<'de> for $name {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
Ok(Self::from_bits_truncate(<$type>::deserialize(deserializer)?))
/// The macro forwards the generation to the `bitflags::bitflags!` macro and implements
/// the default (de)serialization for Discord's bitmask values.
///
/// The flags are created with `T::from_bits_truncate` for the deserialized integer value.
///
/// Use the `bitflags::bitflags! macro directly if a different serde implementation is required.
macro_rules! bitflags {
(
$(#[$outer:meta])*
$vis:vis struct $BitFlags:ident: $T:ty {
$(
$(#[$inner:ident $($args:tt)*])*
const $Flag:ident = $value:expr;
)*
}

$($t:tt)*
) => {
bitflags::bitflags! {
$(#[$outer])*
$vis struct $BitFlags: $T {
$(
$(#[$inner $($args)*])*
const $Flag = $value;
)*
}
}

impl serde::ser::Serialize for $name {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
bitflags!(__impl_serde $BitFlags: $T);

bitflags! {
$($t)*
}
};
(__impl_serde $BitFlags:ident: $T:tt) => {
impl<'de> serde::de::Deserialize<'de> for $BitFlags {
fn deserialize<D: serde::de::Deserializer<'de>>(deserializer: D) -> std::result::Result<Self, D::Error> {
Ok(Self::from_bits_truncate(<$T>::deserialize(deserializer)?))
}
}

impl serde::ser::Serialize for $BitFlags {
fn serialize<S: serde::ser::Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
self.bits().serialize(serializer)
}
}
};
() => {};
}
3 changes: 0 additions & 3 deletions src/model/channel/message.rs
Expand Up @@ -5,7 +5,6 @@ use std::fmt::Display;
#[cfg(all(feature = "cache", feature = "model"))]
use std::fmt::Write;

use bitflags::bitflags;
use chrono::{DateTime, Utc};
#[cfg(feature = "simd-json")]
use simd_json::ValueAccess;
Expand Down Expand Up @@ -1253,8 +1252,6 @@ bitflags! {
}
}

impl_bitflags_serde!(MessageFlags: u64);

#[cfg(feature = "model")]
impl MessageId {
/// Returns a link referencing this message. When clicked, users will jump to the message.
Expand Down
5 changes: 0 additions & 5 deletions src/model/gateway.rs
@@ -1,6 +1,5 @@
//! Models pertaining to the gateway.

use bitflags::bitflags;
use url::Url;

use super::prelude::*;
Expand Down Expand Up @@ -317,8 +316,6 @@ bitflags! {
}
}

impl_bitflags_serde!(ActivityFlags: u64);

/// Information about an activity's party.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
Expand Down Expand Up @@ -670,8 +667,6 @@ bitflags! {
}
}

impl_bitflags_serde!(GatewayIntents: u64);

#[cfg(feature = "model")]
impl GatewayIntents {
/// Gets all of the intents that don't are considered privileged by Discord.
Expand Down
3 changes: 0 additions & 3 deletions src/model/guild/member.rs
Expand Up @@ -4,7 +4,6 @@ use std::borrow::Cow;
use std::cmp::Reverse;
use std::fmt::{Display, Formatter, Result as FmtResult};

use bitflags::bitflags;
use chrono::{DateTime, Utc};

#[cfg(feature = "model")]
Expand Down Expand Up @@ -725,5 +724,3 @@ bitflags! {
const NOTIFICATIONS = 1 << 0;
}
}

impl_bitflags_serde!(ThreadMemberFlags: u64);
4 changes: 0 additions & 4 deletions src/model/guild/system_channel.rs
@@ -1,5 +1,3 @@
use bitflags::bitflags;

bitflags! {
/// Describes a system channel flags.
#[derive(Default)]
Expand All @@ -14,5 +12,3 @@ bitflags! {
const SUPPRESS_JOIN_NOTIFICATION_REPLIES = 1 << 3;
}
}

impl_bitflags_serde!(SystemChannelFlags: u64);
3 changes: 0 additions & 3 deletions src/model/interactions/mod.rs
Expand Up @@ -6,7 +6,6 @@ pub mod ping;

use application_command::ApplicationCommandInteraction;
use autocomplete::AutocompleteInteraction;
use bitflags::bitflags;
use message_component::MessageComponentInteraction;
use modal::ModalSubmitInteraction;
use ping::PingInteraction;
Expand Down Expand Up @@ -210,8 +209,6 @@ bitflags! {
}
}

impl_bitflags_serde!(InteractionApplicationCommandCallbackDataFlags: u64);

/// Sent when a [`Message`] is a response to an [`Interaction`].
///
/// [`Message`]: crate::model::channel::Message
Expand Down
3 changes: 1 addition & 2 deletions src/model/permissions.rs
Expand Up @@ -44,7 +44,6 @@
#[cfg(feature = "model")]
use std::fmt::{Display, Formatter, Result as FmtResult};

use bitflags::bitflags;
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};

Expand Down Expand Up @@ -220,7 +219,7 @@ pub const PRESET_VOICE: Permissions = Permissions {
bits: Permissions::CONNECT.bits | Permissions::SPEAK.bits | Permissions::USE_VAD.bits,
};

bitflags! {
bitflags::bitflags! {
/// A set of permissions that can be assigned to [`User`]s and [`Role`]s via
/// [`PermissionOverwrite`]s, roles globally in a [`Guild`], and to
/// [`GuildChannel`]s.
Expand Down
3 changes: 0 additions & 3 deletions src/model/user.rs
Expand Up @@ -4,7 +4,6 @@ use std::fmt;
#[cfg(feature = "model")]
use std::fmt::Write;

use bitflags::bitflags;
#[cfg(feature = "model")]
use futures::future::{BoxFuture, FutureExt};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -693,8 +692,6 @@ bitflags! {
}
}

impl_bitflags_serde!(UserPublicFlags: u32);

impl Default for User {
/// Initializes a [`User`] with default values. Setting the following:
/// - **id** to `UserId(210)`
Expand Down

0 comments on commit 4d5f4f1

Please sign in to comment.