Skip to content

Commit 05e2f33

Browse files
committed
Add helper CowStrVisitor and CowBytesVisitor types
1 parent b9de365 commit 05e2f33

File tree

1 file changed

+286
-0
lines changed

1 file changed

+286
-0
lines changed

serde/src/de/value.rs

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,6 +1727,292 @@ where
17271727

17281728
////////////////////////////////////////////////////////////////////////////////
17291729

1730+
/// A visitor and a seed which is able to return borrowed `Cow<str>`.
1731+
///
1732+
/// Serde implementation is generic for any `Cow<T>` and because visitor has no
1733+
/// hint methods for arbitrary borrowing types, [`Cow`] is always deserialized as
1734+
/// [`Cow::Owned`] variant. This visitor and seed allows to deserialize borrowed
1735+
/// variant of a [`Cow`] for a string.
1736+
///
1737+
/// This is useful when you want to read `Cow` from a [`MapAccess`] or a [`SeqAccess`].
1738+
///
1739+
/// # Example
1740+
///
1741+
/// This example implements a simple XML DOM node:
1742+
/// ```
1743+
/// # use serde::de::{DeserializeSeed, Deserializer, MapAccess, Visitor};
1744+
/// # use serde::de::value::CowStrVisitor;
1745+
/// # use std::borrow::Cow;
1746+
/// #
1747+
/// struct Element<'a> {
1748+
/// name: Cow<'a, str>,
1749+
/// children: Vec<Node<'a>>,
1750+
/// }
1751+
/// enum Node<'a> {
1752+
/// Text(Cow<'a, str>),
1753+
/// Element(Element<'a>),
1754+
/// }
1755+
///
1756+
/// impl<'de> Visitor<'de> for Element<'de> {
1757+
/// type Value = Self;
1758+
///
1759+
/// fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1760+
/// f.write_str("a map")
1761+
/// }
1762+
///
1763+
/// fn visit_map<A>(mut self, mut map: A) -> Result<Self::Value, A::Error>
1764+
/// where
1765+
/// A: MapAccess<'de>,
1766+
/// {
1767+
/// while let Some(key) = map.next_key_seed(CowStrVisitor)? {
1768+
/// if "$text" == key {
1769+
/// let text = map.next_value_seed(CowStrVisitor)?;
1770+
/// self.children.push(Node::Text(text));
1771+
/// } else {
1772+
/// let elem = Element { name: key, children: Vec::new() };
1773+
/// let elem = map.next_value_seed(elem)?;
1774+
/// self.children.push(Node::Element(elem));
1775+
/// }
1776+
/// }
1777+
/// Ok(self)
1778+
/// }
1779+
/// }
1780+
///
1781+
/// impl<'de> DeserializeSeed<'de> for Element<'de> {
1782+
/// type Value = Self;
1783+
///
1784+
/// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
1785+
/// where
1786+
/// D: Deserializer<'de>,
1787+
/// {
1788+
/// deserializer.deserialize_map(self)
1789+
/// }
1790+
/// }
1791+
/// ```
1792+
///
1793+
/// [`MapAccess`]: crate::de::MapAccess
1794+
#[cfg(any(feature = "std", feature = "alloc"))]
1795+
#[doc(alias = "CowStrSeed")]
1796+
#[derive(Debug, Copy, Clone)]
1797+
pub struct CowStrVisitor;
1798+
1799+
#[cfg(any(feature = "std", feature = "alloc"))]
1800+
impl<'de> Visitor<'de> for CowStrVisitor {
1801+
type Value = Cow<'de, str>;
1802+
1803+
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1804+
f.write_str("a string")
1805+
}
1806+
1807+
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
1808+
where
1809+
E: de::Error,
1810+
{
1811+
Ok(Cow::Owned(v.to_owned()))
1812+
}
1813+
1814+
#[inline]
1815+
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
1816+
where
1817+
E: de::Error,
1818+
{
1819+
Ok(Cow::Borrowed(v))
1820+
}
1821+
1822+
#[inline]
1823+
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
1824+
where
1825+
E: de::Error,
1826+
{
1827+
Ok(Cow::Owned(v))
1828+
}
1829+
1830+
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
1831+
where
1832+
E: de::Error,
1833+
{
1834+
match str::from_utf8(v) {
1835+
Ok(s) => Ok(Cow::Owned(s.to_owned())),
1836+
Err(_) => Err(de::Error::invalid_value(de::Unexpected::Bytes(v), &self)),
1837+
}
1838+
}
1839+
1840+
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
1841+
where
1842+
E: de::Error,
1843+
{
1844+
match str::from_utf8(v) {
1845+
Ok(s) => Ok(Cow::Borrowed(s)),
1846+
Err(_) => Err(de::Error::invalid_value(de::Unexpected::Bytes(v), &self)),
1847+
}
1848+
}
1849+
1850+
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
1851+
where
1852+
E: de::Error,
1853+
{
1854+
match String::from_utf8(v) {
1855+
Ok(s) => Ok(Cow::Owned(s)),
1856+
Err(e) => Err(de::Error::invalid_value(
1857+
de::Unexpected::Bytes(&e.into_bytes()),
1858+
&self,
1859+
)),
1860+
}
1861+
}
1862+
}
1863+
1864+
#[cfg(any(feature = "std", feature = "alloc"))]
1865+
impl<'de> de::DeserializeSeed<'de> for CowStrVisitor {
1866+
type Value = Cow<'de, str>;
1867+
1868+
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
1869+
where
1870+
D: Deserializer<'de>,
1871+
{
1872+
deserializer.deserialize_string(self)
1873+
}
1874+
}
1875+
1876+
////////////////////////////////////////////////////////////////////////////////
1877+
1878+
/// A visitor and a seed which is able to return borrowed `Cow<[u8]>`.
1879+
///
1880+
/// Serde implementation is generic for any `Cow<T>` and because visitor has no
1881+
/// hint methods for arbitrary borrowing types, [`Cow`] is always deserialized as
1882+
/// [`Cow::Owned`] variant. This visitor and seed allows to deserialize borrowed
1883+
/// variant of a [`Cow`] for a byte slice.
1884+
///
1885+
/// This is useful when you want to read `Cow` from a [`MapAccess`] or a [`SeqAccess`].
1886+
///
1887+
/// # Example
1888+
///
1889+
/// This example implements a simple XML DOM node:
1890+
/// ```
1891+
/// # use serde::de::{DeserializeSeed, Deserializer, MapAccess, Visitor};
1892+
/// # use serde::de::value::CowBytesVisitor;
1893+
/// # use std::borrow::Cow;
1894+
/// #
1895+
/// struct Element<'a> {
1896+
/// name: Cow<'a, [u8]>,
1897+
/// children: Vec<Node<'a>>,
1898+
/// }
1899+
/// enum Node<'a> {
1900+
/// Text(Cow<'a, [u8]>),
1901+
/// Element(Element<'a>),
1902+
/// }
1903+
///
1904+
/// impl<'de> Visitor<'de> for Element<'de> {
1905+
/// type Value = Self;
1906+
///
1907+
/// fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1908+
/// f.write_str("a map")
1909+
/// }
1910+
///
1911+
/// fn visit_map<A>(mut self, mut map: A) -> Result<Self::Value, A::Error>
1912+
/// where
1913+
/// A: MapAccess<'de>,
1914+
/// {
1915+
/// while let Some(key) = map.next_key_seed(CowBytesVisitor)? {
1916+
/// if *b"$text" == *key {
1917+
/// let text = map.next_value_seed(CowBytesVisitor)?;
1918+
/// self.children.push(Node::Text(text));
1919+
/// } else {
1920+
/// let elem = Element { name: key, children: Vec::new() };
1921+
/// let elem = map.next_value_seed(elem)?;
1922+
/// self.children.push(Node::Element(elem));
1923+
/// }
1924+
/// }
1925+
/// Ok(self)
1926+
/// }
1927+
/// }
1928+
///
1929+
/// impl<'de> DeserializeSeed<'de> for Element<'de> {
1930+
/// type Value = Self;
1931+
///
1932+
/// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
1933+
/// where
1934+
/// D: Deserializer<'de>,
1935+
/// {
1936+
/// deserializer.deserialize_map(self)
1937+
/// }
1938+
/// }
1939+
/// ```
1940+
///
1941+
/// [`MapAccess`]: crate::de::MapAccess
1942+
#[cfg(any(feature = "std", feature = "alloc"))]
1943+
#[doc(alias = "CowBytesSeed")]
1944+
#[derive(Debug, Copy, Clone)]
1945+
pub struct CowBytesVisitor;
1946+
1947+
#[cfg(any(feature = "std", feature = "alloc"))]
1948+
impl<'de> Visitor<'de> for CowBytesVisitor {
1949+
type Value = Cow<'de, [u8]>;
1950+
1951+
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1952+
f.write_str("a byte array")
1953+
}
1954+
1955+
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
1956+
where
1957+
E: de::Error,
1958+
{
1959+
Ok(Cow::Owned(v.as_bytes().to_owned()))
1960+
}
1961+
1962+
#[inline]
1963+
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
1964+
where
1965+
E: de::Error,
1966+
{
1967+
Ok(Cow::Borrowed(v.as_bytes()))
1968+
}
1969+
1970+
#[inline]
1971+
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
1972+
where
1973+
E: de::Error,
1974+
{
1975+
Ok(Cow::Owned(v.into_bytes()))
1976+
}
1977+
1978+
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
1979+
where
1980+
E: de::Error,
1981+
{
1982+
Ok(Cow::Owned(v.to_owned()))
1983+
}
1984+
1985+
#[inline]
1986+
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
1987+
where
1988+
E: de::Error,
1989+
{
1990+
Ok(Cow::Borrowed(v))
1991+
}
1992+
1993+
#[inline]
1994+
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
1995+
where
1996+
E: de::Error,
1997+
{
1998+
Ok(Cow::Owned(v))
1999+
}
2000+
}
2001+
2002+
#[cfg(any(feature = "std", feature = "alloc"))]
2003+
impl<'de> de::DeserializeSeed<'de> for CowBytesVisitor {
2004+
type Value = Cow<'de, [u8]>;
2005+
2006+
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
2007+
where
2008+
D: Deserializer<'de>,
2009+
{
2010+
deserializer.deserialize_byte_buf(self)
2011+
}
2012+
}
2013+
2014+
////////////////////////////////////////////////////////////////////////////////
2015+
17302016
mod private {
17312017
use crate::lib::*;
17322018

0 commit comments

Comments
 (0)