Merge pull request #851 from serde-rs/rawkey

Support deserializing map key as &RawValue
This commit is contained in:
David Tolnay 2022-01-22 15:30:38 -08:00 committed by GitHub
commit cbb0342ba0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 1 deletions

View File

@ -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"

View File

@ -2184,10 +2184,18 @@ where
}
#[inline]
fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
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)
}

View File

@ -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<D>(deserializer: D) -> Result<Self, D::Error>
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<H: Hasher>(&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() {