Skip to content

Commit 0ca5a69

Browse files
committed
Add regression test for issue 845
1 parent 6691977 commit 0ca5a69

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

tests/regression/issue845.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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+
20+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
21+
formatter.write_str("an integer or string")
22+
}
23+
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+
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+
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+
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]
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+
}

0 commit comments

Comments
 (0)