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