1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use serde::{Deserialize, Deserializer, Serialize, Serializer};

#[derive(Debug, Deserialize, Serialize)]
pub struct Bool(
    #[serde(
        serialize_with = "serialize_bool",
        deserialize_with = "deserialize_bool"
    )]
    pub bool,
);

impl Bool {
    pub fn get(&self) -> bool {
        self.0
    }
}

pub fn deserialize_bool<'de, D>(d: D) -> Result<bool, D::Error>
where
    D: Deserializer<'de>,
{
    struct Visitor;

    impl<'v> serde::de::Visitor<'v> for Visitor {
        type Value = bool;

        fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
            write!(f, "A string or number encoded bool")
        }

        fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
        where
            E: serde::de::Error,
        {
            if v == 0 {
                Ok(false)
            } else if v == 1 {
                Ok(true)
            } else {
                Err(E::custom("Invalid value for boolean"))
            }
        }

        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
        where
            E: serde::de::Error,
        {
            if let Ok(value) = v.parse::<u64>() {
                if value == 0 {
                    Ok(false)
                } else if value == 1 {
                    Ok(true)
                } else {
                    Err(E::custom("invalid value for boolean"))
                }
            } else {
                Err(E::custom("invalid value for boolean"))
            }
        }
    }

    d.deserialize_any(Visitor)
}

pub fn serialize_bool<S>(value: &bool, s: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    let value = if !value { 0u32 } else { 1u32 };
    s.serialize_u32(value)
}

pub fn deserialize_bool_optional<'de, D>(d: D) -> Result<Option<bool>, D::Error>
where
    D: Deserializer<'de>,
{
    Ok(Option::<Bool>::deserialize(d)?.map(|v| v.get()))
}

pub fn serialize_bool_optional<S>(value: &Option<bool>, s: S) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    value.map(Bool).serialize(s)
}