1use std::fmt;
7
8use serde::{
9 de::{Error, Unexpected},
10 Deserializer,
11};
12use serde_with::DeserializeAs;
13
14pub struct PermissiveBool;
22
23impl<'de> DeserializeAs<'de, bool> for PermissiveBool {
24 fn deserialize_as<D>(deserializer: D) -> Result<bool, D::Error>
25 where
26 D: Deserializer<'de>,
27 {
28 struct Visitor;
29
30 impl<'vde> serde::de::Visitor<'vde> for Visitor {
31 type Value = bool;
32
33 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
34 formatter.write_str("a boolean, string, integer, or floating-point number")
35 }
36
37 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
38 where
39 E: Error,
40 {
41 Ok(value)
42 }
43
44 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
45 where
46 E: Error,
47 {
48 match value.to_lowercase().as_str() {
49 "true" => Ok(true),
50 "false" => Ok(false),
51 _ => Err(Error::invalid_value(
52 Unexpected::Str(value),
53 &"\"true\" or \"false\" (case insensitive)",
54 )),
55 }
56 }
57
58 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
59 where
60 E: Error,
61 {
62 match value {
63 0 => Ok(false),
64 1 => Ok(true),
65 _ => Err(Error::invalid_value(Unexpected::Signed(value), &"0 or 1")),
66 }
67 }
68
69 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
70 where
71 E: Error,
72 {
73 match value {
74 0 => Ok(false),
75 1 => Ok(true),
76 _ => Err(Error::invalid_value(Unexpected::Unsigned(value), &"0 or 1")),
77 }
78 }
79
80 fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
81 where
82 E: Error,
83 {
84 match value {
85 0.0 => Ok(false),
86 1.0 => Ok(true),
87 _ => Err(Error::invalid_value(Unexpected::Float(value), &"0.0 or 1.0")),
88 }
89 }
90 }
91
92 deserializer.deserialize_any(Visitor)
93 }
94}