From 6a3fb68979b7e9da0f690f6f07e907045c1b30d9 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 22 Jan 2022 15:17:01 -0800 Subject: [PATCH 1/2] Add test of deserializing a &RawValue in map key position Currently fails with: ---- test_raw_value_in_map_key stdout ---- thread 'test_borrowed_raw_value' panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: newtype struct, expected any valid JSON value", line: 1, column: 2)', tests/test.rs:2230:52 --- Cargo.toml | 1 + tests/test.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 8c63f9b..795974f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ ryu = "1.0" [dev-dependencies] automod = "1.0" +ref-cast = "1.0" rustversion = "1.0" serde_bytes = "0.11" serde_derive = "1.0" diff --git a/tests/test.rs b/tests/test.rs index bfcb529..084a7b7 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -2193,6 +2193,46 @@ fn test_borrowed_raw_value() { assert_eq!(r#"["a",42,{"foo": "bar"},null]"#, array_to_string); } +#[cfg(feature = "raw_value")] +#[test] +fn test_raw_value_in_map_key() { + use ref_cast::RefCast; + + #[derive(RefCast)] + #[repr(transparent)] + struct RawMapKey(RawValue); + + impl<'de> Deserialize<'de> for &'de RawMapKey { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let raw_value = <&RawValue>::deserialize(deserializer)?; + Ok(RawMapKey::ref_cast(raw_value)) + } + } + + impl PartialEq for RawMapKey { + fn eq(&self, other: &Self) -> bool { + self.0.get() == other.0.get() + } + } + + impl Eq for RawMapKey {} + + impl Hash for RawMapKey { + fn hash(&self, hasher: &mut H) { + self.0.get().hash(hasher); + } + } + + let map_from_str: std::collections::HashMap<&RawMapKey, &RawValue> = + serde_json::from_str(r#" {"\\k":"\\v"} "#).unwrap(); + let (map_k, map_v) = map_from_str.into_iter().next().unwrap(); + assert_eq!("\"\\\\k\"", map_k.0.get()); + assert_eq!("\"\\\\v\"", map_v.get()); +} + #[cfg(feature = "raw_value")] #[test] fn test_boxed_raw_value() { From e5cdfcc7ee482238a654afbf3c0116a9f852ce79 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 22 Jan 2022 15:08:36 -0800 Subject: [PATCH 2/2] Support deserializing map key as &RawValue --- src/de.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/de.rs b/src/de.rs index bf103f0..ffd0d48 100644 --- a/src/de.rs +++ b/src/de.rs @@ -2184,10 +2184,18 @@ where } #[inline] - fn deserialize_newtype_struct(self, _name: &'static str, visitor: V) -> Result + fn deserialize_newtype_struct(self, name: &'static str, visitor: V) -> Result where V: de::Visitor<'de>, { + #[cfg(feature = "raw_value")] + { + if name == crate::raw::TOKEN { + return self.de.deserialize_raw_value(visitor); + } + } + + let _ = name; visitor.visit_newtype_struct(self) }