Coverage Report

Created: 2025-06-24 06:14

/rust/registry/src/index.crates.io-6f17d22bba15001f/bitflags-2.9.1/src/external/serde.rs
Line
Count
Source (jump to first uncovered line)
1
//! Specialized serialization for flags types using `serde`.
2
3
use crate::{
4
    parser::{self, ParseHex, WriteHex},
5
    Flags,
6
};
7
use core::{fmt, str};
8
use serde::{
9
    de::{Error, Visitor},
10
    Deserialize, Deserializer, Serialize, Serializer,
11
};
12
13
/**
14
Serialize a set of flags as a human-readable string or their underlying bits.
15
16
Any unknown bits will be retained.
17
*/
18
0
pub fn serialize<B: Flags, S: Serializer>(flags: &B, serializer: S) -> Result<S::Ok, S::Error>
19
0
where
20
0
    B::Bits: WriteHex + Serialize,
21
0
{
22
0
    // Serialize human-readable flags as a string like `"A | B"`
23
0
    if serializer.is_human_readable() {
24
0
        serializer.collect_str(&parser::AsDisplay(flags))
25
    }
26
    // Serialize non-human-readable flags directly as the underlying bits
27
    else {
28
0
        flags.bits().serialize(serializer)
29
    }
30
0
}
31
32
/**
33
Deserialize a set of flags from a human-readable string or their underlying bits.
34
35
Any unknown bits will be retained.
36
*/
37
0
pub fn deserialize<'de, B: Flags, D: Deserializer<'de>>(deserializer: D) -> Result<B, D::Error>
38
0
where
39
0
    B::Bits: ParseHex + Deserialize<'de>,
40
0
{
41
0
    if deserializer.is_human_readable() {
42
        // Deserialize human-readable flags by parsing them from strings like `"A | B"`
43
        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
0
            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
52
0
                formatter.write_str("a string value of `|` separated flags")
53
0
            }
54
55
0
            fn visit_str<E: Error>(self, flags: &str) -> Result<Self::Value, E> {
56
0
                parser::from_str(flags).map_err(|e| E::custom(e))
57
0
            }
58
        }
59
60
0
        deserializer.deserialize_str(FlagsVisitor(Default::default()))
61
    } else {
62
        // Deserialize non-human-readable flags directly from the underlying bits
63
0
        let bits = B::Bits::deserialize(deserializer)?;
64
65
0
        Ok(B::from_bits_retain(bits))
66
    }
67
0
}
68
69
#[cfg(test)]
70
mod 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
}