serde_flexible/deserialize/
as_string.rs

1use serde::de::{Deserializer, Error, Visitor};
2use std::fmt;
3
4const EXPECTED: &str = "a string, bool, or a number";
5
6pub fn as_string<'de, D: Deserializer<'de>>(deserializer: D) -> Result<String, D::Error> {
7    deserializer.deserialize_any(AsString)
8}
9
10struct AsString;
11
12impl<'de> Visitor<'de> for AsString {
13    type Value = String;
14
15    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
16        formatter.write_str(EXPECTED)
17    }
18
19    fn visit_bool<E: Error>(self, v: bool) -> Result<Self::Value, E> {
20        Ok(v.to_string())
21    }
22    fn visit_i64<E: Error>(self, v: i64) -> Result<Self::Value, E> {
23        Ok(v.to_string())
24    }
25    fn visit_u64<E: Error>(self, v: u64) -> Result<Self::Value, E> {
26        Ok(v.to_string())
27    }
28    fn visit_f64<E: Error>(self, v: f64) -> Result<Self::Value, E> {
29        Ok(v.to_string())
30    }
31    fn visit_str<E: Error>(self, v: &str) -> Result<Self::Value, E> {
32        Ok(v.to_owned())
33    }
34}
35
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40    use serde::Deserialize;
41
42    #[derive(Debug, Deserialize, PartialEq)]
43    struct Test {
44        #[serde(deserialize_with = "as_string")]
45        str: String,
46    }
47
48    #[test]
49    fn test_base_good_parse() {
50        assert_eq!(serde_json::from_str::<Test>(r#"{"str": "Foo Boo" }"#).unwrap().str, "Foo Boo");
51        assert_eq!(serde_json::from_str::<Test>(r#"{"str": "hello"   }"#).unwrap().str, "hello");
52        assert_eq!(serde_json::from_str::<Test>(r#"{"str": 100       }"#).unwrap().str, "100");
53        assert_eq!(serde_json::from_str::<Test>(r#"{"str": true      }"#).unwrap().str, "true");
54        assert_eq!(serde_json::from_str::<Test>(r#"{"str": false     }"#).unwrap().str, "false");
55        assert_eq!(serde_json::from_str::<Test>(r#"{"str": 12345     }"#).unwrap().str, "12345");
56        assert_eq!(serde_json::from_str::<Test>(r#"{"str": -12345    }"#).unwrap().str, "-12345");
57        assert_eq!(serde_json::from_str::<Test>(r#"{"str": -0        }"#).unwrap().str, "-0");
58        assert_eq!(serde_json::from_str::<Test>(r#"{"str": 0         }"#).unwrap().str, "0");
59        assert_eq!(serde_json::from_str::<Test>(r#"{"str": 3.14      }"#).unwrap().str, "3.14");
60    }
61
62    #[test]
63    fn test_base_error() {
64        assert!(serde_json::from_str::<Test>(r#"{"str": null         }"#).is_err());
65        assert!(serde_json::from_str::<Test>(r#"{"str": ["hello"]]   }"#).is_err());
66    }
67}