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/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) } 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() {