serde_flexible/deserialize/
as_string.rs1use 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}