1 //! `bitflags` crate Serde shims 2 //! 3 //! To enable to `bitflags` shims, add it as a dependency: 4 //! 5 //! ```toml 6 //! [dependencies] 7 //! bitflags_serde_shim = "0.2" 8 //! ``` 9 //! 10 //! Full example: 11 //! 12 //! ``` 13 //! #[macro_use] 14 //! extern crate serde_derive; 15 //! extern crate serde_json; 16 //! 17 //! #[macro_use] 18 //! extern crate bitflags; 19 //! #[macro_use] // required for impl_serde_for_bitflags 20 //! extern crate bitflags_serde_shim; 21 //! 22 //! bitflags! { 23 //! // Note that `impl_serde_for_bitflags` requires the flag type to 24 //! // implement `Serialize` and `Deserialize`. 25 //! // 26 //! // All primitive integer types satisfy this requirement. 27 //! pub struct Permission: u32 { 28 //! const SEND_MESSAGE = 0x00000001; 29 //! const EDIT_MESSAGE = 0x00000002; 30 //! const KICK_MEMBER = 0x00000004; 31 //! const BAN_MEMBER = 0x00000008; 32 //! } 33 //! } 34 //! 35 //! impl_serde_for_bitflags!(Permission); 36 //! 37 //! fn main() { 38 //! let test = Permission::SEND_MESSAGE | Permission::EDIT_MESSAGE; 39 //! 40 //! assert_eq!(serde_json::to_string(&test).unwrap(), "3"); 41 //! 42 //! assert_eq!(serde_json::from_str::<Permission>("3").unwrap(), test); 43 //! 44 //! assert!(serde_json::from_str::<Permission>("51").is_err()); 45 //! } 46 //! ``` 47 #![cfg_attr(not(feature = "std"), no_std)] 48 49 #[doc(hidden)] 50 pub extern crate serde; 51 52 #[doc(hidden)] 53 #[cfg(not(feature = "std"))] 54 pub use core::result::Result; 55 56 #[doc(hidden)] 57 #[cfg(feature = "std")] 58 pub use std::result::Result; 59 60 /// Implements `Serialize` and `Deserialize` for a `bitflags!` generated structure. 61 /// 62 /// Note that `impl_serde_for_bitflags` requires the flag type to 63 /// implement `Serialize` and `Deserialize`. 64 /// 65 /// All primitive integer types satisfy these requirements. 66 /// 67 /// See the [`bitflags`](../bitflags_serde_shim/index.html) shim for a full example. 68 #[macro_export] 69 macro_rules! impl_serde_for_bitflags { 70 ($name:ident) => { 71 impl $crate::serde::Serialize for $name { 72 fn serialize<S>(&self, serializer: S) -> $crate::Result<S::Ok, S::Error> 73 where 74 S: $crate::serde::Serializer, 75 { 76 self.bits().serialize(serializer) 77 } 78 } 79 80 #[cfg(feature = "std")] 81 impl<'de> $crate::serde::Deserialize<'de> for $name { 82 fn deserialize<D>(deserializer: D) -> $crate::Result<$name, D::Error> 83 where 84 D: $crate::serde::Deserializer<'de>, 85 { 86 let value = <_ as $crate::serde::Deserialize<'de>>::deserialize(deserializer)?; 87 88 $name::from_bits(value) 89 .ok_or_else(|| $crate::serde::de::Error::custom(format!("Invalid bits {:#X} for {}", value, stringify!($name)))) 90 } 91 } 92 93 #[cfg(not(feature = "std"))] 94 impl<'de> $crate::serde::Deserialize<'de> for $name { 95 fn deserialize<D>(deserializer: D) -> $crate::Result<$name, D::Error> 96 where 97 D: $crate::serde::Deserializer<'de>, 98 { 99 let value = <_ as $crate::serde::Deserialize<'de>>::deserialize(deserializer)?; 100 101 // Use a 'static str for the no_std version 102 $name::from_bits(value) 103 .ok_or_else(|| $crate::serde::de::Error::custom(stringify!(Invalid bits for $name))) 104 } 105 } 106 }; 107 } 108