Skip to content

Commit cbb0342

Browse files
authored
Merge pull request #851 from serde-rs/rawkey
Support deserializing map key as &RawValue
2 parents d8512af + e5cdfcc commit cbb0342

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ ryu = "1.0"
2020

2121
[dev-dependencies]
2222
automod = "1.0"
23+
ref-cast = "1.0"
2324
rustversion = "1.0"
2425
serde_bytes = "0.11"
2526
serde_derive = "1.0"

src/de.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2184,10 +2184,18 @@ where
21842184
}
21852185

21862186
#[inline]
2187-
fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
2187+
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
21882188
where
21892189
V: de::Visitor<'de>,
21902190
{
2191+
#[cfg(feature = "raw_value")]
2192+
{
2193+
if name == crate::raw::TOKEN {
2194+
return self.de.deserialize_raw_value(visitor);
2195+
}
2196+
}
2197+
2198+
let _ = name;
21912199
visitor.visit_newtype_struct(self)
21922200
}
21932201

tests/test.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2193,6 +2193,46 @@ fn test_borrowed_raw_value() {
21932193
assert_eq!(r#"["a",42,{"foo": "bar"},null]"#, array_to_string);
21942194
}
21952195

2196+
#[cfg(feature = "raw_value")]
2197+
#[test]
2198+
fn test_raw_value_in_map_key() {
2199+
use ref_cast::RefCast;
2200+
2201+
#[derive(RefCast)]
2202+
#[repr(transparent)]
2203+
struct RawMapKey(RawValue);
2204+
2205+
impl<'de> Deserialize<'de> for &'de RawMapKey {
2206+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
2207+
where
2208+
D: serde::Deserializer<'de>,
2209+
{
2210+
let raw_value = <&RawValue>::deserialize(deserializer)?;
2211+
Ok(RawMapKey::ref_cast(raw_value))
2212+
}
2213+
}
2214+
2215+
impl PartialEq for RawMapKey {
2216+
fn eq(&self, other: &Self) -> bool {
2217+
self.0.get() == other.0.get()
2218+
}
2219+
}
2220+
2221+
impl Eq for RawMapKey {}
2222+
2223+
impl Hash for RawMapKey {
2224+
fn hash<H: Hasher>(&self, hasher: &mut H) {
2225+
self.0.get().hash(hasher);
2226+
}
2227+
}
2228+
2229+
let map_from_str: std::collections::HashMap<&RawMapKey, &RawValue> =
2230+
serde_json::from_str(r#" {"\\k":"\\v"} "#).unwrap();
2231+
let (map_k, map_v) = map_from_str.into_iter().next().unwrap();
2232+
assert_eq!("\"\\\\k\"", map_k.0.get());
2233+
assert_eq!("\"\\\\v\"", map_v.get());
2234+
}
2235+
21962236
#[cfg(feature = "raw_value")]
21972237
#[test]
21982238
fn test_boxed_raw_value() {

0 commit comments

Comments
 (0)