rust_docs_mcp/
util.rs

1use serde::{Deserializer, de};
2use std::fmt;
3
4/// Custom deserializer that can handle boolean values from strings, booleans, or numbers
5pub fn deserialize_bool_from_anything<'de, D>(deserializer: D) -> Result<bool, D::Error>
6where
7    D: Deserializer<'de>,
8{
9    use serde::de::Visitor;
10
11    struct BoolVisitor;
12
13    impl<'de> Visitor<'de> for BoolVisitor {
14        type Value = bool;
15
16        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
17            formatter.write_str("a boolean, string, or number")
18        }
19
20        fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
21        where
22            E: de::Error,
23        {
24            Ok(value)
25        }
26
27        fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
28        where
29            E: de::Error,
30        {
31            match value.to_lowercase().as_str() {
32                "true" | "1" | "yes" | "on" => Ok(true),
33                "false" | "0" | "no" | "off" | "" => Ok(false),
34                _ => Err(E::custom(format!("cannot parse '{value}' as boolean"))),
35            }
36        }
37
38        fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
39        where
40            E: de::Error,
41        {
42            Ok(value != 0)
43        }
44
45        fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
46        where
47            E: de::Error,
48        {
49            Ok(value != 0)
50        }
51
52        fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
53        where
54            E: de::Error,
55        {
56            Ok(value != 0.0)
57        }
58    }
59
60    deserializer.deserialize_any(BoolVisitor)
61}