//! `bitflags` crate Serde shims //! //! To enable to `bitflags` shims, add it as a dependency: //! //! ```toml //! [dependencies] //! bitflags_serde_shim = "0.2" //! ``` //! //! Full example: //! //! ``` //! #[macro_use] //! extern crate serde_derive; //! extern crate serde_json; //! //! #[macro_use] //! extern crate bitflags; //! #[macro_use] // required for impl_serde_for_bitflags //! extern crate bitflags_serde_shim; //! //! bitflags! { //! // Note that `impl_serde_for_bitflags` requires the flag type to //! // implement `Serialize` and `Deserialize`. //! // //! // All primitive integer types satisfy this requirement. //! pub struct Permission: u32 { //! const SEND_MESSAGE = 0x00000001; //! const EDIT_MESSAGE = 0x00000002; //! const KICK_MEMBER = 0x00000004; //! const BAN_MEMBER = 0x00000008; //! } //! } //! //! impl_serde_for_bitflags!(Permission); //! //! fn main() { //! let test = Permission::SEND_MESSAGE | Permission::EDIT_MESSAGE; //! //! assert_eq!(serde_json::to_string(&test).unwrap(), "3"); //! //! assert_eq!(serde_json::from_str::("3").unwrap(), test); //! //! assert!(serde_json::from_str::("51").is_err()); //! } //! ``` #![cfg_attr(not(feature = "std"), no_std)] #[doc(hidden)] pub extern crate serde; /// Implements `Serialize` and `Deserialize` for a `bitflags!` generated structure. /// /// Note that `impl_serde_for_bitflags` requires the flag type to /// implement `Serialize` and `Deserialize`. /// /// All primitive integer types satisfy these requirements. /// /// See the [`bitflags`](../bitflags_serde_shim/index.html) shim for a full example. #[cfg(not(feature = "std"))] #[macro_export] macro_rules! impl_serde_for_bitflags { ($name:ident) => { impl $crate::serde::Serialize for $name { #[inline] fn serialize(&self, serializer: S) -> core::result::Result where S: $crate::serde::Serializer, { self.bits().serialize(serializer) } } impl<'de> $crate::serde::Deserialize<'de> for $name { #[inline] fn deserialize(deserializer: D) -> core::result::Result<$name, D::Error> where D: $crate::serde::Deserializer<'de>, { let value = <_ as $crate::serde::Deserialize<'de>>::deserialize(deserializer)?; // Use a 'static str for the no_std version $name::from_bits(value) .ok_or_else(|| $crate::serde::de::Error::custom(stringify!(Invalid bits for $name))) } } }; } /// Implements `Serialize` and `Deserialize` for a `bitflags!` generated structure. /// /// Note that `impl_serde_for_bitflags` requires the flag type to /// implement `Serialize` and `Deserialize`. /// /// All primitive integer types satisfy these requirements. /// /// See the [`bitflags`](../bitflags_serde_shim/index.html) shim for a full example. #[cfg(feature = "std")] #[macro_export] macro_rules! impl_serde_for_bitflags { ($name:ident) => { impl $crate::serde::Serialize for $name { #[inline] fn serialize(&self, serializer: S) -> core::result::Result where S: $crate::serde::Serializer, { self.bits().serialize(serializer) } } impl<'de> $crate::serde::Deserialize<'de> for $name { #[inline] fn deserialize(deserializer: D) -> core::result::Result<$name, D::Error> where D: $crate::serde::Deserializer<'de>, { let value = <_ as $crate::serde::Deserialize<'de>>::deserialize(deserializer)?; $name::from_bits(value) .ok_or_else(|| $crate::serde::de::Error::custom(format!(concat!("Invalid bits {:#X} for ", stringify!($name)), value))) } } }; }