Repository: serde-rs/json (language: rust)

Issue:
Implement IntoDeserializer for Value and &Value
An `IntoDeserializer` impl would provide a way to deserialize from these types while constructing exactly the right error type on failure, rather than constructing a `serde_json::Error` and mapping it to a custom error of the target type through its `Display` impl.

```rust
fn f<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
    T: Deserialize<'de>,
    D: Deserializer<'de>,
{
    let mut v = Value::deserialize(deserializer)?;

    /* some manipulation of v */

    T::deserialize(v).map_err(serde::de::Error::custom)
}
```

```diff
- T::deserialize(v).map_err(serde::de::Error::custom)
+ T::deserialize(v.into_deserializer())
```


Discussion / hints:

Fix patch:
diff --git a/src/value/de.rs b/src/value/de.rs
index 3f14abb3b..2090dd009 100644
--- a/src/value/de.rs
+++ b/src/value/de.rs
@@ -482,6 +482,14 @@ impl<'de> IntoDeserializer<'de, Error> for Value {
     }
 }
 
+impl<'de> IntoDeserializer<'de, Error> for &'de Value {
+    type Deserializer = Self;
+
+    fn into_deserializer(self) -> Self::Deserializer {
+        self
+    }
+}
+
 struct VariantDeserializer {
     value: Option<Value>,
 }


Test patch:
diff --git a/tests/test.rs b/tests/test.rs
index acf5de480..8d9a5942a 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -2472,6 +2472,12 @@ fn test_value_into_deserializer() {
     let mut map = BTreeMap::new();
     map.insert("inner", json!({ "string": "Hello World" }));
 
+    let outer = Outer::deserialize(serde::de::value::MapDeserializer::new(
+        map.iter().map(|(k, v)| (*k, v)),
+    ))
+    .unwrap();
+    assert_eq!(outer.inner.string, "Hello World");
+
     let outer = Outer::deserialize(map.into_deserializer()).unwrap();
     assert_eq!(outer.inner.string, "Hello World");
 }