bitflags/external/
serde.rs1use crate::{
4 parser::{self, ParseHex, WriteHex},
5 Flags,
6};
7use core::{fmt, str};
8use serde::{
9 de::{Error, Visitor},
10 Deserialize, Deserializer, Serialize, Serializer,
11};
12
13pub fn serialize<B: Flags, S: Serializer>(flags: &B, serializer: S) -> Result<S::Ok, S::Error>
19where
20 B::Bits: WriteHex + Serialize,
21{
22 if serializer.is_human_readable() {
24 serializer.collect_str(&parser::AsDisplay(flags))
25 }
26 else {
28 flags.bits().serialize(serializer)
29 }
30}
31
32pub fn deserialize<'de, B: Flags, D: Deserializer<'de>>(deserializer: D) -> Result<B, D::Error>
38where
39 B::Bits: ParseHex + Deserialize<'de>,
40{
41 if deserializer.is_human_readable() {
42 struct FlagsVisitor<B>(core::marker::PhantomData<B>);
44
45 impl<'de, B: Flags> Visitor<'de> for FlagsVisitor<B>
46 where
47 B::Bits: ParseHex,
48 {
49 type Value = B;
50
51 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
52 formatter.write_str("a string value of `|` separated flags")
53 }
54
55 fn visit_str<E: Error>(self, flags: &str) -> Result<Self::Value, E> {
56 parser::from_str(flags).map_err(|e| E::custom(e))
57 }
58 }
59
60 deserializer.deserialize_str(FlagsVisitor(Default::default()))
61 } else {
62 let bits = B::Bits::deserialize(deserializer)?;
64
65 Ok(B::from_bits_retain(bits))
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use serde_test::{assert_tokens, Configure, Token::*};
72 bitflags! {
73 #[derive(serde_derive::Serialize, serde_derive::Deserialize, Debug, PartialEq, Eq)]
74 #[serde(transparent)]
75 struct SerdeFlags: u32 {
76 const A = 1;
77 const B = 2;
78 const C = 4;
79 const D = 8;
80 }
81 }
82
83 #[test]
84 fn test_serde_bitflags_default() {
85 assert_tokens(&SerdeFlags::empty().readable(), &[Str("")]);
86
87 assert_tokens(&SerdeFlags::empty().compact(), &[U32(0)]);
88
89 assert_tokens(&(SerdeFlags::A | SerdeFlags::B).readable(), &[Str("A | B")]);
90
91 assert_tokens(&(SerdeFlags::A | SerdeFlags::B).compact(), &[U32(1 | 2)]);
92 }
93}