aboutsummaryrefslogtreecommitdiff
path: root/vendor/serde_json/tests/regression/issue845.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/serde_json/tests/regression/issue845.rs')
-rw-r--r--vendor/serde_json/tests/regression/issue845.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/vendor/serde_json/tests/regression/issue845.rs b/vendor/serde_json/tests/regression/issue845.rs
new file mode 100644
index 0000000..e8b0c0f
--- /dev/null
+++ b/vendor/serde_json/tests/regression/issue845.rs
@@ -0,0 +1,73 @@
+#![allow(clippy::trait_duplication_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/8757
+
+use serde::{Deserialize, Deserializer};
+use std::fmt::{self, Display};
+use std::marker::PhantomData;
+use std::str::FromStr;
+
+pub struct NumberVisitor<T> {
+ marker: PhantomData<T>,
+}
+
+impl<'de, T> serde::de::Visitor<'de> for NumberVisitor<T>
+where
+ T: TryFrom<u64> + TryFrom<i64> + FromStr,
+ <T as TryFrom<u64>>::Error: Display,
+ <T as TryFrom<i64>>::Error: Display,
+ <T as FromStr>::Err: Display,
+{
+ type Value = T;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("an integer or string")
+ }
+
+ fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
+ where
+ E: serde::de::Error,
+ {
+ T::try_from(v).map_err(serde::de::Error::custom)
+ }
+
+ fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
+ where
+ E: serde::de::Error,
+ {
+ T::try_from(v).map_err(serde::de::Error::custom)
+ }
+
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+ where
+ E: serde::de::Error,
+ {
+ v.parse().map_err(serde::de::Error::custom)
+ }
+}
+
+fn 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,
+{
+ deserializer.deserialize_any(NumberVisitor {
+ marker: PhantomData,
+ })
+}
+
+#[derive(Deserialize, Debug)]
+pub struct Struct {
+ #[serde(deserialize_with = "deserialize_integer_or_string")]
+ pub i: i64,
+}
+
+#[test]
+fn test() {
+ let j = r#" {"i":100} "#;
+ println!("{:?}", serde_json::from_str::<Struct>(j).unwrap());
+
+ let j = r#" {"i":"100"} "#;
+ println!("{:?}", serde_json::from_str::<Struct>(j).unwrap());
+}