• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use serde::{Deserialize, Deserializer};
2 use std::convert::TryFrom;
3 use std::fmt::{self, Display};
4 use std::marker::PhantomData;
5 use std::str::FromStr;
6 
7 pub struct NumberVisitor<T> {
8     marker: PhantomData<T>,
9 }
10 
11 impl<'de, T> serde::de::Visitor<'de> for NumberVisitor<T>
12 where
13     T: TryFrom<u64> + TryFrom<i64> + FromStr,
14     <T as TryFrom<u64>>::Error: Display,
15     <T as TryFrom<i64>>::Error: Display,
16     <T as FromStr>::Err: Display,
17 {
18     type Value = T;
19 
expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result20     fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
21         formatter.write_str("an integer or string")
22     }
23 
visit_u64<E>(self, v: u64) -> Result<Self::Value, E> where E: serde::de::Error,24     fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
25     where
26         E: serde::de::Error,
27     {
28         T::try_from(v).map_err(serde::de::Error::custom)
29     }
30 
visit_i64<E>(self, v: i64) -> Result<Self::Value, E> where E: serde::de::Error,31     fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
32     where
33         E: serde::de::Error,
34     {
35         T::try_from(v).map_err(serde::de::Error::custom)
36     }
37 
visit_str<E>(self, v: &str) -> Result<Self::Value, E> where E: serde::de::Error,38     fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
39     where
40         E: serde::de::Error,
41     {
42         v.parse().map_err(serde::de::Error::custom)
43     }
44 }
45 
deserialize_integer_or_string<'de, D, T>(deserializer: D) -> Result<T, D::Error> where D: Deserializer<'de>, T: TryFrom<u64> + TryFrom<i64> + FromStr, <T as TryFrom<u64>>::Error: Display, <T as TryFrom<i64>>::Error: Display, <T as FromStr>::Err: Display,46 fn deserialize_integer_or_string<'de, D, T>(deserializer: D) -> Result<T, D::Error>
47 where
48     D: Deserializer<'de>,
49     T: TryFrom<u64> + TryFrom<i64> + FromStr,
50     <T as TryFrom<u64>>::Error: Display,
51     <T as TryFrom<i64>>::Error: Display,
52     <T as FromStr>::Err: Display,
53 {
54     deserializer.deserialize_any(NumberVisitor {
55         marker: PhantomData,
56     })
57 }
58 
59 #[derive(Deserialize, Debug)]
60 pub struct Struct {
61     #[serde(deserialize_with = "deserialize_integer_or_string")]
62     pub i: i64,
63 }
64 
65 #[test]
test()66 fn test() {
67     let j = r#" {"i":100} "#;
68     println!("{:?}", serde_json::from_str::<Struct>(j).unwrap());
69 
70     let j = r#" {"i":"100"} "#;
71     println!("{:?}", serde_json::from_str::<Struct>(j).unwrap());
72 }
73