diff --git a/Cargo.toml b/Cargo.toml index bad0c164d..285b077e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ bytecheck = { version = "0.6", optional = true } serde = { version = "1", features = ["derive", "rc"] } serde_json = "1" -bitflags = "1.2" +bitflags = "2" serde_repr = "0.1" enum-primitive-derive = "0.3" num-traits = "0.2" @@ -60,7 +60,7 @@ ahash = { version = "0.8", optional = true } postgres-types = { version = "0.2.1", optional = true } bytes = { version = "1", optional = true } -rusqlite = { version = "0.30.0", optional = true } +rusqlite = { version = "0.31.0", optional = true } crc32fast = { version = "1", optional = true } ciborium = { version = "0.2", optional = true } diff --git a/common/Cargo.toml b/common/Cargo.toml index a66070670..8bca96cbd 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -9,11 +9,11 @@ license = "MIT" [dependencies] schemars = { version = "0.8.12", optional = true } serde = { version = "1.0.163", features = ["derive"] } -serde_shims = { version = "0.2", features = ["bitflags"] } +bitflags_serde_shim = { version = "0.2.5", default_features = false } postgres-types = { version = "0.2.1", optional = true } bytes = { version = "1", optional = true } -rusqlite = { version = "0.30.0", optional = true } +rusqlite = { version = "0.31.0", optional = true } rkyv = { version = "0.7", optional = true, default-features = false, features = ["validation"] } rend = { version = "0.4", optional = true, default-features = false } diff --git a/common/src/lib.rs b/common/src/lib.rs index 5e8f3a14f..f3954f79d 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -9,7 +9,7 @@ pub extern crate rkyv; #[cfg(feature = "rkyv")] pub extern crate rend; -pub extern crate serde_shims; +pub extern crate bitflags_serde_shim; pub mod db; pub mod fixed; diff --git a/common/src/ser.rs b/common/src/ser.rs index f9d4bd7f3..7a516bb4f 100644 --- a/common/src/ser.rs +++ b/common/src/ser.rs @@ -58,7 +58,7 @@ macro_rules! impl_rkyv_for_pod { #[macro_export] macro_rules! impl_serde_for_bitflags { ($name:ident) => { - $crate::serde_shims::impl_serde_for_bitflags!($name); + $crate::bitflags_serde_shim::impl_serde_for_bitflags!($name); $crate::impl_rkyv_for_pod!($name + CheckBytes); }; @@ -68,7 +68,7 @@ macro_rules! impl_serde_for_bitflags { #[macro_export] macro_rules! impl_serde_for_bitflags { ($name:ident) => { - $crate::serde_shims::impl_serde_for_bitflags!($name); + $crate::bitflags_serde_shim::impl_serde_for_bitflags!($name); }; } diff --git a/src/api/command.rs b/src/api/command.rs index 286fa7e99..fe654db3f 100644 --- a/src/api/command.rs +++ b/src/api/command.rs @@ -9,6 +9,7 @@ pub(crate) mod sealed { use crate::models::Permissions; bitflags::bitflags! { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct CommandFlags: u8 { const AUTHORIZED = 1 << 0; const HAS_BODY = 1 << 1; diff --git a/src/models/asset.rs b/src/models/asset.rs index 36745bb2e..596841ce9 100644 --- a/src/models/asset.rs +++ b/src/models/asset.rs @@ -2,6 +2,7 @@ bitflags::bitflags! { /// NOTE: Formats are as individual bitflags (rather than some integer value) so we can do /// simpler queries when matching valid formats. A user can select formats A, B and C, and testing for a match /// can be done with a single bitwise-AND operation, rather than many comparisons or an `IN ARRAY` operation. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct AssetFlags: i16 { /// 7-bit unsigned integer for quality from `[0-128)` /// @@ -20,23 +21,23 @@ bitflags::bitflags! { const FORMAT_WEBM = 1 << 14; const FORMATS = 0 - | Self::FORMAT_PNG.bits - | Self::FORMAT_JPEG.bits - | Self::FORMAT_GIF.bits - | Self::FORMAT_AVIF.bits - | Self::FORMAT_WEBM.bits; + | Self::FORMAT_PNG.bits() + | Self::FORMAT_JPEG.bits() + | Self::FORMAT_GIF.bits() + | Self::FORMAT_AVIF.bits() + | Self::FORMAT_WEBM.bits(); /// These formats don't have widespread support yet, so don't include them by default const MAYBE_UNSUPPORTED_FORMATS = 0 - | Self::FORMAT_AVIF.bits; + | Self::FORMAT_AVIF.bits(); const FLAGS = 0 - | Self::HAS_ALPHA.bits - | Self::ANIMATED.bits; + | Self::HAS_ALPHA.bits() + | Self::ANIMATED.bits(); const FORMATS_AND_FLAGS = 0 - | Self::FORMATS.bits - | Self::FLAGS.bits; + | Self::FORMATS.bits() + | Self::FLAGS.bits(); } } @@ -62,7 +63,7 @@ impl AssetFlags { } pub const fn quality(&self) -> u8 { - self.intersection(Self::QUALITY).bits as u8 + self.intersection(Self::QUALITY).bits() as u8 } pub fn from_ext(ext: &str) -> Self { diff --git a/src/models/emote.rs b/src/models/emote.rs index 915ab4c45..78860e2e9 100644 --- a/src/models/emote.rs +++ b/src/models/emote.rs @@ -1,6 +1,7 @@ use super::*; bitflags::bitflags! { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct EmoteFlags: i16 { const ANIMATED = 1 << 0; const STICKER = 1 << 1; diff --git a/src/models/gateway.rs b/src/models/gateway.rs index 4f625a171..a48c2d1b6 100644 --- a/src/models/gateway.rs +++ b/src/models/gateway.rs @@ -1,6 +1,7 @@ use super::*; bitflags::bitflags! { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Intent: u32 { /// - PARTY_CREATE /// - PARTY_UPDATE diff --git a/src/models/message.rs b/src/models/message.rs index 13cc46fb0..56180fe96 100644 --- a/src/models/message.rs +++ b/src/models/message.rs @@ -1,6 +1,7 @@ use super::*; bitflags::bitflags! { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct MessageFlags: i32 { /// This message has been deleted const DELETED = 1 << 0; diff --git a/src/models/party/mod.rs b/src/models/party/mod.rs index 0daace34d..1f6801c03 100644 --- a/src/models/party/mod.rs +++ b/src/models/party/mod.rs @@ -6,7 +6,7 @@ mod prefs; pub use prefs::*; bitflags::bitflags! { - #[derive(Default)] + #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct PartyFlags: i32 { /// Must have a verified email address const EMAIL = 1 << 0; @@ -32,11 +32,11 @@ bitflags::bitflags! { const LANGUAGE = 0b11_11_11 << (32 - 6); const SECURITY = 0 - | Self::EMAIL.bits - | Self::PHONE.bits - | Self::NEW_USER.bits - | Self::NEW_MEMBER.bits - | Self::MFA_ENABLED.bits; + | Self::EMAIL.bits() + | Self::PHONE.bits() + | Self::NEW_USER.bits() + | Self::NEW_MEMBER.bits() + | Self::MFA_ENABLED.bits(); } } @@ -106,6 +106,7 @@ impl Deref for Party { } bitflags::bitflags! { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct PartyMemberFlags: i16 { const BANNED = 1 << 0; } @@ -149,6 +150,7 @@ impl Deref for PartyMember { } bitflags::bitflags! { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct PinFolderFlags: i32 { const COLOR = 0x00_FF_FF_FFu32 as i32; // top 24 bits } diff --git a/src/models/party/prefs.rs b/src/models/party/prefs.rs index d6a369cd1..b4fb092d9 100644 --- a/src/models/party/prefs.rs +++ b/src/models/party/prefs.rs @@ -8,6 +8,7 @@ use super::*; use crate::models::Locale; bitflags::bitflags! { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct PartyPrefsFlags: i32 { const DEFAULT_FLAGS = 0; diff --git a/src/models/permission.rs b/src/models/permission.rs index 98aef6cb9..d41915820 100644 --- a/src/models/permission.rs +++ b/src/models/permission.rs @@ -20,19 +20,20 @@ bitflags::bitflags! { /// This type is 16-byte aligned to ensure consistent alignment /// of the inner `u128`` across all platforms. #[repr(C, align(16))] + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Permissions: u128 { const DEFAULT = 0 - | Self::CHANGE_NICKNAME.bits - | Self::VIEW_ROOM.bits - | Self::READ_MESSAGE_HISTORY.bits - | Self::SEND_MESSAGES.bits - | Self::USE_EXTERNAL_EMOTES.bits - | Self::ADD_REACTIONS.bits - | Self::EMBED_LINKS.bits - | Self::ATTACH_FILES.bits - | Self::SEND_TTS_MESSAGES.bits - | Self::CONNECT.bits - | Self::SPEAK.bits; + | Self::CHANGE_NICKNAME.bits() + | Self::VIEW_ROOM.bits() + | Self::READ_MESSAGE_HISTORY.bits() + | Self::SEND_MESSAGES.bits() + | Self::USE_EXTERNAL_EMOTES.bits() + | Self::ADD_REACTIONS.bits() + | Self::EMBED_LINKS.bits() + | Self::ATTACH_FILES.bits() + | Self::SEND_TTS_MESSAGES.bits() + | Self::CONNECT.bits() + | Self::SPEAK.bits(); const ADMINISTRATOR = 1u128 << 0; const CREATE_INVITE = 1u128 << 1; @@ -54,8 +55,8 @@ bitflags::bitflags! { const DEFAULT_ONLY = 1u128 << 20; const VIEW_ROOM = 1u128 << 30; - const READ_MESSAGE_HISTORY = 1u128 << 31 | Self::VIEW_ROOM.bits; - const SEND_MESSAGES = 1u128 << 32 | Self::VIEW_ROOM.bits; + const READ_MESSAGE_HISTORY = 1u128 << 31 | Self::VIEW_ROOM.bits(); + const SEND_MESSAGES = 1u128 << 32 | Self::VIEW_ROOM.bits(); const MANAGE_MESSAGES = 1u128 << 33; const MUTE_MEMBERS = 1u128 << 34; const DEAFEN_MEMBERS = 1u128 << 35; diff --git a/src/models/presence.rs b/src/models/presence.rs index bb4ab1dad..eee9a88a1 100644 --- a/src/models/presence.rs +++ b/src/models/presence.rs @@ -2,6 +2,7 @@ use super::*; bitflags::bitflags! { /// NOTE: These flags are ordered such that larger values take precedence + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct UserPresenceFlags: i16 { const OFFLINE = 0; const AWAY = 1 << 0; diff --git a/src/models/role.rs b/src/models/role.rs index b27417814..22f298135 100644 --- a/src/models/role.rs +++ b/src/models/role.rs @@ -1,7 +1,7 @@ use super::*; bitflags::bitflags! { - #[derive(Default)] + #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct RoleFlags: i16 { const HOIST = 1 << 0; const MENTIONABLE = 1 << 1; diff --git a/src/models/room.rs b/src/models/room.rs index 024addd17..9fc9ed58f 100644 --- a/src/models/room.rs +++ b/src/models/room.rs @@ -20,6 +20,7 @@ pub enum RoomKind { } bitflags::bitflags! { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct RoomFlags: i16 { const KIND = 0xF; // first four bits are the kind const NSFW = 1 << 4; @@ -35,13 +36,13 @@ impl RoomFlags { pub fn kind(self) -> RoomKind { // all rooms derive from the text room, so basic queries // will still function if the SDK is not updated as it should - RoomKind::from_i16(self.bits & 0xF).unwrap_or(RoomKind::Text) + RoomKind::from_i16(self.bits() & 0xF).unwrap_or(RoomKind::Text) } } impl From for RoomFlags { fn from(value: RoomKind) -> Self { - unsafe { RoomFlags::from_bits_unchecked(value as u8 as i16) } + RoomFlags::from_bits_retain(value as u8 as i16) } } diff --git a/src/models/thread.rs b/src/models/thread.rs index 17ac1bf26..17aa31fc7 100644 --- a/src/models/thread.rs +++ b/src/models/thread.rs @@ -1,6 +1,7 @@ use super::*; bitflags::bitflags! { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ThreadFlags: i16 { /// Forum-style thread const FORUM = 1 << 0; diff --git a/src/models/user/mod.rs b/src/models/user/mod.rs index 05b9a7f14..598e2eebc 100644 --- a/src/models/user/mod.rs +++ b/src/models/user/mod.rs @@ -5,6 +5,7 @@ pub use prefs::*; bitflags::bitflags! { /// NOTE: Remember to clear flag caches when they change + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct UserFlags: i32 { const BANNED = 1 << 0; const VERIFIED = 1 << 1; @@ -33,36 +34,36 @@ bitflags::bitflags! { const RESERVED_4 = 1 << 15; const RESERVED = 0 - | Self::RESERVED_1.bits - | Self::RESERVED_2.bits - | Self::RESERVED_3.bits - | Self::RESERVED_4.bits; + | Self::RESERVED_1.bits() + | Self::RESERVED_2.bits() + | Self::RESERVED_3.bits() + | Self::RESERVED_4.bits(); /// Always strip these from public responses const PRIVATE_FLAGS = 0 - | Self::BANNED.bits - | Self::VERIFIED.bits - | Self::MFA_ENABLED.bits - | Self::NEEDS_PASSWORD_RESET.bits - | Self::EXTRA_STORAGE.bits - | Self::RESERVED.bits; + | Self::BANNED.bits() + | Self::VERIFIED.bits() + | Self::MFA_ENABLED.bits() + | Self::NEEDS_PASSWORD_RESET.bits() + | Self::EXTRA_STORAGE.bits() + | Self::RESERVED.bits(); /// elevation level integer const ELEVATION = 0 - | Self::ELEVATION_1.bits - | Self::ELEVATION_2.bits - | Self::ELEVATION_3.bits; + | Self::ELEVATION_1.bits() + | Self::ELEVATION_2.bits() + | Self::ELEVATION_3.bits(); /// premium level integer const PREMIUM = 0 - | Self::PREMIUM_1.bits - | Self::PREMIUM_2.bits - | Self::PREMIUM_3.bits; + | Self::PREMIUM_1.bits() + | Self::PREMIUM_2.bits() + | Self::PREMIUM_3.bits(); /// extra storage level integer const EXTRA_STORAGE = 0 - | Self::EXTRA_STORAGE_1.bits - | Self::EXTRA_STORAGE_2.bits; + | Self::EXTRA_STORAGE_1.bits() + | Self::EXTRA_STORAGE_2.bits(); } } @@ -112,14 +113,14 @@ impl UserFlags { } bitflags::bitflags! { - #[derive(Default)] + #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct UserProfileBits: i32 { const AVATAR_ROUNDNESS = 0x7F; // 127, lower 7 bits const OVERRIDE_COLOR = 0x80; // 8th bit const PRIMARY_COLOR = 0xFF_FF_FF_00u32 as i32; // top 24 bits } - #[derive(Default)] + #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ExtraUserProfileBits: i32 { const OVERRIDE_COLOR = 0x80; // 8th bit const SECONDARY_COLOR = 0xFF_FF_FF_00u32 as i32; // top 24 bits diff --git a/src/models/user/prefs.rs b/src/models/user/prefs.rs index b59425eb1..e3a6c4e64 100644 --- a/src/models/user/prefs.rs +++ b/src/models/user/prefs.rs @@ -43,6 +43,7 @@ common::enum_codes! { } bitflags::bitflags! { + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct UserPrefsFlags: i32 { /// Reduce movement and animations in the UI const REDUCE_ANIMATIONS = 1 << 0; @@ -94,13 +95,13 @@ bitflags::bitflags! { const HIDE_NSFW_EMBEDS = 1 << 22; const DEFAULT_FLAGS = 0 - | Self::ALLOW_DMS.bits - | Self::GROUP_LINES.bits - | Self::ENABLE_SPELLCHECK.bits - | Self::SHOW_MEDIA_METADATA.bits - | Self::SHOW_DATE_CHANGE.bits - | Self::SHOW_GREY_IMAGE_BG.bits - | Self::SHOW_ATTACHMENT_GRID.bits; + | Self::ALLOW_DMS.bits() + | Self::GROUP_LINES.bits() + | Self::ENABLE_SPELLCHECK.bits() + | Self::SHOW_MEDIA_METADATA.bits() + | Self::SHOW_DATE_CHANGE.bits() + | Self::SHOW_GREY_IMAGE_BG.bits() + | Self::SHOW_ATTACHMENT_GRID.bits(); } }