serde
serde copied to clipboard
Add helper CowStrVisitor and CowBytesVisitor types
As all known, when you deserialize Cow, it will always be deserialized as Owned, which makes it difficult to implement effective deserialization when you manually want to deserialize Cow<str> or Cow<[u8]>. This PR adds two helper types, CowStrVisitor and CowBytesVisitor, which both serves as a Visitor and a DeserializeSeed and allows you to read borrowed data from, for example, MapAccess:
use serde::de::{DeserializeSeed, Deserializer, MapAccess, Visitor};
use serde::de::value::CowStrVisitor;
use std::borrow::Cow;
/// A simple XML DOM node.
struct Element<'a> {
name: Cow<'a, str>,
children: Vec<Node<'a>>,
}
enum Node<'a> {
Text(Cow<'a, str>),
Element(Element<'a>),
}
impl<'de> Visitor<'de> for Element<'de> {
type Value = Self;
fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.write_str("a map")
}
fn visit_map<A>(mut self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
while let Some(key) = map.next_key_seed(CowStrVisitor)? {
if "$text" == key {
let text = map.next_value_seed(CowStrVisitor)?;
self.children.push(Node::Text(text));
} else {
let elem = Element { name: key, children: Vec::new() };
let elem = map.next_value_seed(elem)?;
self.children.push(Node::Element(elem));
}
}
Ok(self)
}
}
impl<'de> DeserializeSeed<'de> for Element<'de> {
type Value = Self;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_map(self)
}
}
Doctests is not enough?
They just test compilation, not execution actually producing Cow::Borrowed
Ah, yes. Will be soon
@dtolnay this seems like a good addition to serde. even if it could live out of tree, it's for basic libstd types