From 43a97878ce14b72f0981164f87f2e35e14151312 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:22:09 +0200 Subject: Adding upstream version 110.0.1. Signed-off-by: Daniel Baumann --- third_party/rust/serde_bytes/src/bytebuf.rs | 253 ++++++++++++++++++++++++++++ third_party/rust/serde_bytes/src/bytes.rs | 172 +++++++++++++++++++ third_party/rust/serde_bytes/src/de.rs | 229 +++++++++++++++++++++++++ third_party/rust/serde_bytes/src/lib.rs | 113 +++++++++++++ third_party/rust/serde_bytes/src/ser.rs | 136 +++++++++++++++ 5 files changed, 903 insertions(+) create mode 100644 third_party/rust/serde_bytes/src/bytebuf.rs create mode 100644 third_party/rust/serde_bytes/src/bytes.rs create mode 100644 third_party/rust/serde_bytes/src/de.rs create mode 100644 third_party/rust/serde_bytes/src/lib.rs create mode 100644 third_party/rust/serde_bytes/src/ser.rs (limited to 'third_party/rust/serde_bytes/src') diff --git a/third_party/rust/serde_bytes/src/bytebuf.rs b/third_party/rust/serde_bytes/src/bytebuf.rs new file mode 100644 index 0000000000..0c2daa6e25 --- /dev/null +++ b/third_party/rust/serde_bytes/src/bytebuf.rs @@ -0,0 +1,253 @@ +use core::borrow::{Borrow, BorrowMut}; +use core::cmp::{self, Ordering}; +use core::fmt::{self, Debug}; +use core::hash::{Hash, Hasher}; +use core::ops::{Deref, DerefMut}; + +#[cfg(feature = "alloc")] +use alloc::boxed::Box; +#[cfg(feature = "alloc")] +use alloc::string::String; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; + +use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor}; +use serde::ser::{Serialize, Serializer}; + +use crate::Bytes; + +/// Wrapper around `Vec` to serialize and deserialize efficiently. +/// +/// ``` +/// use std::collections::HashMap; +/// use std::io; +/// +/// use serde_bytes::ByteBuf; +/// +/// fn deserialize_bytebufs() -> bincode::Result<()> { +/// let example_data = [ +/// 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 116, +/// 119, 111, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 111, 110, 101]; +/// +/// let map: HashMap = bincode::deserialize(&example_data[..])?; +/// +/// println!("{:?}", map); +/// +/// Ok(()) +/// } +/// # +/// # fn main() { +/// # deserialize_bytebufs().unwrap(); +/// # } +/// ``` +#[derive(Clone, Default, Eq, Ord)] +pub struct ByteBuf { + bytes: Vec, +} + +impl ByteBuf { + /// Construct a new, empty `ByteBuf`. + pub fn new() -> Self { + ByteBuf::from(Vec::new()) + } + + /// Construct a new, empty `ByteBuf` with the specified capacity. + pub fn with_capacity(cap: usize) -> Self { + ByteBuf::from(Vec::with_capacity(cap)) + } + + /// Wrap existing bytes in a `ByteBuf`. + pub fn from>>(bytes: T) -> Self { + ByteBuf { + bytes: bytes.into(), + } + } + + /// Unwrap the vector of byte underlying this `ByteBuf`. + pub fn into_vec(self) -> Vec { + self.bytes + } + + #[allow(missing_docs)] + pub fn into_boxed_bytes(self) -> Box { + self.bytes.into_boxed_slice().into() + } + + // This would hit "cannot move out of borrowed content" if invoked through + // the Deref impl; make it just work. + #[doc(hidden)] + pub fn into_boxed_slice(self) -> Box<[u8]> { + self.bytes.into_boxed_slice() + } + + #[doc(hidden)] + #[allow(clippy::should_implement_trait)] + pub fn into_iter(self) -> as IntoIterator>::IntoIter { + self.bytes.into_iter() + } +} + +impl Debug for ByteBuf { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.bytes, f) + } +} + +impl AsRef<[u8]> for ByteBuf { + fn as_ref(&self) -> &[u8] { + &self.bytes + } +} + +impl AsMut<[u8]> for ByteBuf { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.bytes + } +} + +impl Deref for ByteBuf { + type Target = Vec; + + fn deref(&self) -> &Self::Target { + &self.bytes + } +} + +impl DerefMut for ByteBuf { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.bytes + } +} + +impl Borrow for ByteBuf { + fn borrow(&self) -> &Bytes { + Bytes::new(&self.bytes) + } +} + +impl BorrowMut for ByteBuf { + fn borrow_mut(&mut self) -> &mut Bytes { + unsafe { &mut *(&mut self.bytes as &mut [u8] as *mut [u8] as *mut Bytes) } + } +} + +impl PartialEq for ByteBuf +where + Rhs: ?Sized + AsRef<[u8]>, +{ + fn eq(&self, other: &Rhs) -> bool { + self.as_ref().eq(other.as_ref()) + } +} + +impl PartialOrd for ByteBuf +where + Rhs: ?Sized + AsRef<[u8]>, +{ + fn partial_cmp(&self, other: &Rhs) -> Option { + self.as_ref().partial_cmp(other.as_ref()) + } +} + +impl Hash for ByteBuf { + fn hash(&self, state: &mut H) { + self.bytes.hash(state); + } +} + +impl IntoIterator for ByteBuf { + type Item = u8; + type IntoIter = as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.bytes.into_iter() + } +} + +impl<'a> IntoIterator for &'a ByteBuf { + type Item = &'a u8; + type IntoIter = <&'a [u8] as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.bytes.iter() + } +} + +impl<'a> IntoIterator for &'a mut ByteBuf { + type Item = &'a mut u8; + type IntoIter = <&'a mut [u8] as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.bytes.iter_mut() + } +} + +impl Serialize for ByteBuf { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_bytes(&self.bytes) + } +} + +struct ByteBufVisitor; + +impl<'de> Visitor<'de> for ByteBufVisitor { + type Value = ByteBuf; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("byte array") + } + + fn visit_seq(self, mut visitor: V) -> Result + where + V: SeqAccess<'de>, + { + let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096); + let mut bytes = Vec::with_capacity(len); + + while let Some(b) = visitor.next_element()? { + bytes.push(b); + } + + Ok(ByteBuf::from(bytes)) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: Error, + { + Ok(ByteBuf::from(v)) + } + + fn visit_byte_buf(self, v: Vec) -> Result + where + E: Error, + { + Ok(ByteBuf::from(v)) + } + + fn visit_str(self, v: &str) -> Result + where + E: Error, + { + Ok(ByteBuf::from(v)) + } + + fn visit_string(self, v: String) -> Result + where + E: Error, + { + Ok(ByteBuf::from(v)) + } +} + +impl<'de> Deserialize<'de> for ByteBuf { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_byte_buf(ByteBufVisitor) + } +} diff --git a/third_party/rust/serde_bytes/src/bytes.rs b/third_party/rust/serde_bytes/src/bytes.rs new file mode 100644 index 0000000000..2cfa75e6d6 --- /dev/null +++ b/third_party/rust/serde_bytes/src/bytes.rs @@ -0,0 +1,172 @@ +use core::cmp::Ordering; +use core::fmt::{self, Debug}; +use core::hash::{Hash, Hasher}; +use core::ops::{Deref, DerefMut}; + +#[cfg(feature = "alloc")] +use alloc::borrow::ToOwned; + +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + +#[cfg(any(feature = "std", feature = "alloc"))] +use crate::ByteBuf; + +use serde::de::{Deserialize, Deserializer}; +use serde::ser::{Serialize, Serializer}; + +/// Wrapper around `[u8]` to serialize and deserialize efficiently. +/// +/// ``` +/// use std::collections::HashMap; +/// use std::io; +/// +/// use serde_bytes::Bytes; +/// +/// fn print_encoded_cache() -> bincode::Result<()> { +/// let mut cache = HashMap::new(); +/// cache.insert(3, Bytes::new(b"three")); +/// cache.insert(2, Bytes::new(b"two")); +/// cache.insert(1, Bytes::new(b"one")); +/// +/// bincode::serialize_into(&mut io::stdout(), &cache) +/// } +/// # +/// # fn main() { +/// # print_encoded_cache().unwrap(); +/// # } +/// ``` +#[derive(Eq, Ord)] +#[repr(C)] +pub struct Bytes { + bytes: [u8], +} + +impl Bytes { + /// Wrap an existing `&[u8]`. + pub fn new(bytes: &[u8]) -> &Self { + unsafe { &*(bytes as *const [u8] as *const Bytes) } + } +} + +impl Debug for Bytes { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + Debug::fmt(&self.bytes, f) + } +} + +impl AsRef<[u8]> for Bytes { + fn as_ref(&self) -> &[u8] { + &self.bytes + } +} + +impl AsMut<[u8]> for Bytes { + fn as_mut(&mut self) -> &mut [u8] { + &mut self.bytes + } +} + +impl Deref for Bytes { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.bytes + } +} + +impl DerefMut for Bytes { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.bytes + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl ToOwned for Bytes { + type Owned = ByteBuf; + + fn to_owned(&self) -> Self::Owned { + ByteBuf::from(&self.bytes) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl From> for Box { + fn from(bytes: Box<[u8]>) -> Self { + unsafe { Box::from_raw(Box::into_raw(bytes) as *mut Bytes) } + } +} + +impl<'a> Default for &'a Bytes { + fn default() -> Self { + Bytes::new(&[]) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl Default for Box { + fn default() -> Self { + ByteBuf::new().into_boxed_bytes() + } +} + +impl PartialEq for Bytes +where + Rhs: ?Sized + AsRef<[u8]>, +{ + fn eq(&self, other: &Rhs) -> bool { + self.as_ref().eq(other.as_ref()) + } +} + +impl PartialOrd for Bytes +where + Rhs: ?Sized + AsRef<[u8]>, +{ + fn partial_cmp(&self, other: &Rhs) -> Option { + self.as_ref().partial_cmp(other.as_ref()) + } +} + +impl Hash for Bytes { + fn hash(&self, state: &mut H) { + self.bytes.hash(state); + } +} + +impl<'a> IntoIterator for &'a Bytes { + type Item = &'a u8; + type IntoIter = <&'a [u8] as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.bytes.iter() + } +} + +impl<'a> IntoIterator for &'a mut Bytes { + type Item = &'a mut u8; + type IntoIter = <&'a mut [u8] as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.bytes.iter_mut() + } +} + +impl Serialize for Bytes { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_bytes(&self.bytes) + } +} + +impl<'a, 'de: 'a> Deserialize<'de> for &'a Bytes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // serde::Deserialize for &[u8] is already optimized, so simply forward to that. + Deserialize::deserialize(deserializer).map(Bytes::new) + } +} diff --git a/third_party/rust/serde_bytes/src/de.rs b/third_party/rust/serde_bytes/src/de.rs new file mode 100644 index 0000000000..e4a4732eea --- /dev/null +++ b/third_party/rust/serde_bytes/src/de.rs @@ -0,0 +1,229 @@ +use crate::Bytes; +use core::fmt; +use core::marker::PhantomData; +use serde::de::{Error, Visitor}; +use serde::Deserializer; + +#[cfg(any(feature = "std", feature = "alloc"))] +use crate::ByteBuf; + +#[cfg(any(feature = "std", feature = "alloc"))] +use core::cmp; + +#[cfg(feature = "alloc")] +use alloc::borrow::Cow; +#[cfg(all(feature = "std", not(feature = "alloc")))] +use std::borrow::Cow; + +#[cfg(feature = "alloc")] +use alloc::boxed::Box; +#[cfg(feature = "alloc")] +use alloc::string::String; +#[cfg(feature = "alloc")] +use alloc::vec::Vec; + +#[cfg(any(feature = "std", feature = "alloc"))] +use serde::de::SeqAccess; + +/// Types that can be deserialized via `#[serde(with = "serde_bytes")]`. +pub trait Deserialize<'de>: Sized { + #[allow(missing_docs)] + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>; +} + +impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // serde::Deserialize for &[u8] is already optimized, so simply forward to that. + serde::Deserialize::deserialize(deserializer) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de> Deserialize<'de> for Vec { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(ByteBuf::into_vec) + } +} + +impl<'de: 'a, 'a> Deserialize<'de> for &'a Bytes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // serde::Deserialize for &[u8] is already optimized, so simply forward to that. + serde::Deserialize::deserialize(deserializer).map(Bytes::new) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de> Deserialize<'de> for ByteBuf { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // Via the serde::Deserialize impl for ByteBuf. + serde::Deserialize::deserialize(deserializer) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]> { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct CowVisitor; + + impl<'de> Visitor<'de> for CowVisitor { + type Value = Cow<'de, [u8]>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a byte array") + } + + fn visit_borrowed_bytes(self, v: &'de [u8]) -> Result + where + E: Error, + { + Ok(Cow::Borrowed(v)) + } + + fn visit_borrowed_str(self, v: &'de str) -> Result + where + E: Error, + { + Ok(Cow::Borrowed(v.as_bytes())) + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: Error, + { + Ok(Cow::Owned(v.to_vec())) + } + + fn visit_str(self, v: &str) -> Result + where + E: Error, + { + Ok(Cow::Owned(v.as_bytes().to_vec())) + } + + fn visit_byte_buf(self, v: Vec) -> Result + where + E: Error, + { + Ok(Cow::Owned(v)) + } + + fn visit_string(self, v: String) -> Result + where + E: Error, + { + Ok(Cow::Owned(v.into_bytes())) + } + + fn visit_seq(self, mut visitor: V) -> Result + where + V: SeqAccess<'de>, + { + let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096); + let mut bytes = Vec::with_capacity(len); + + while let Some(b) = visitor.next_element()? { + bytes.push(b); + } + + Ok(Cow::Owned(bytes)) + } + } + + deserializer.deserialize_bytes(CowVisitor) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, Bytes> { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let cow: Cow<[u8]> = Deserialize::deserialize(deserializer)?; + match cow { + Cow::Borrowed(bytes) => Ok(Cow::Borrowed(Bytes::new(bytes))), + Cow::Owned(bytes) => Ok(Cow::Owned(ByteBuf::from(bytes))), + } + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de> Deserialize<'de> for Box<[u8]> { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(Vec::into_boxed_slice) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'de> Deserialize<'de> for Box { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let bytes: Box<[u8]> = Deserialize::deserialize(deserializer)?; + Ok(bytes.into()) + } +} + +impl<'de, T> Deserialize<'de> for Option +where + T: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct BytesVisitor { + out: PhantomData, + } + + impl<'de, T> Visitor<'de> for BytesVisitor + where + T: Deserialize<'de>, + { + type Value = Option; + + fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("optional byte array") + } + + fn visit_unit(self) -> Result { + Ok(None) + } + + fn visit_none(self) -> Result { + Ok(None) + } + + fn visit_some(self, deserializer: D) -> Result + where + D: Deserializer<'de>, + { + T::deserialize(deserializer).map(Some) + } + } + + let visitor = BytesVisitor { out: PhantomData }; + deserializer.deserialize_option(visitor) + } +} diff --git a/third_party/rust/serde_bytes/src/lib.rs b/third_party/rust/serde_bytes/src/lib.rs new file mode 100644 index 0000000000..4ead3cb109 --- /dev/null +++ b/third_party/rust/serde_bytes/src/lib.rs @@ -0,0 +1,113 @@ +//! Wrapper types to enable optimized handling of `&[u8]` and `Vec`. +//! +//! Without specialization, Rust forces Serde to treat `&[u8]` just like any +//! other slice and `Vec` just like any other vector. In reality this +//! particular slice and vector can often be serialized and deserialized in a +//! more efficient, compact representation in many formats. +//! +//! When working with such a format, you can opt into specialized handling of +//! `&[u8]` by wrapping it in `serde_bytes::Bytes` and `Vec` by wrapping it +//! in `serde_bytes::ByteBuf`. +//! +//! Additionally this crate supports the Serde `with` attribute to enable +//! efficient handling of `&[u8]` and `Vec` in structs without needing a +//! wrapper type. +//! +//! ``` +//! # use serde_derive::{Deserialize, Serialize}; +//! use serde::{Deserialize, Serialize}; +//! +//! #[derive(Deserialize, Serialize)] +//! struct Efficient<'a> { +//! #[serde(with = "serde_bytes")] +//! bytes: &'a [u8], +//! +//! #[serde(with = "serde_bytes")] +//! byte_buf: Vec, +//! } +//! ``` + +#![doc(html_root_url = "https://docs.rs/serde_bytes/0.11.8")] +#![cfg_attr(not(feature = "std"), no_std)] +#![deny(missing_docs)] +#![allow( + clippy::missing_errors_doc, + clippy::must_use_candidate, + clippy::needless_doctest_main +)] + +mod bytes; +mod de; +mod ser; + +#[cfg(any(feature = "std", feature = "alloc"))] +mod bytebuf; + +#[cfg(feature = "alloc")] +extern crate alloc; + +#[cfg(any(feature = "std", feature = "alloc"))] +use serde::Deserializer; + +use serde::Serializer; + +pub use crate::bytes::Bytes; +pub use crate::de::Deserialize; +pub use crate::ser::Serialize; + +#[cfg(any(feature = "std", feature = "alloc"))] +pub use crate::bytebuf::ByteBuf; + +/// Serde `serialize_with` function to serialize bytes efficiently. +/// +/// This function can be used with either of the following Serde attributes: +/// +/// - `#[serde(with = "serde_bytes")]` +/// - `#[serde(serialize_with = "serde_bytes::serialize")]` +/// +/// ``` +/// # use serde_derive::Serialize; +/// use serde::Serialize; +/// +/// #[derive(Serialize)] +/// struct Efficient<'a> { +/// #[serde(with = "serde_bytes")] +/// bytes: &'a [u8], +/// +/// #[serde(with = "serde_bytes")] +/// byte_buf: Vec, +/// } +/// ``` +pub fn serialize(bytes: &T, serializer: S) -> Result +where + T: ?Sized + Serialize, + S: Serializer, +{ + Serialize::serialize(bytes, serializer) +} + +/// Serde `deserialize_with` function to deserialize bytes efficiently. +/// +/// This function can be used with either of the following Serde attributes: +/// +/// - `#[serde(with = "serde_bytes")]` +/// - `#[serde(deserialize_with = "serde_bytes::deserialize")]` +/// +/// ``` +/// # use serde_derive::Deserialize; +/// use serde::Deserialize; +/// +/// #[derive(Deserialize)] +/// struct Packet { +/// #[serde(with = "serde_bytes")] +/// payload: Vec, +/// } +/// ``` +#[cfg(any(feature = "std", feature = "alloc"))] +pub fn deserialize<'de, T, D>(deserializer: D) -> Result +where + T: Deserialize<'de>, + D: Deserializer<'de>, +{ + Deserialize::deserialize(deserializer) +} diff --git a/third_party/rust/serde_bytes/src/ser.rs b/third_party/rust/serde_bytes/src/ser.rs new file mode 100644 index 0000000000..1cbed9f757 --- /dev/null +++ b/third_party/rust/serde_bytes/src/ser.rs @@ -0,0 +1,136 @@ +use crate::Bytes; +use serde::Serializer; + +#[cfg(any(feature = "std", feature = "alloc"))] +use crate::ByteBuf; + +#[cfg(feature = "alloc")] +use alloc::borrow::Cow; +#[cfg(all(feature = "std", not(feature = "alloc")))] +use std::borrow::Cow; + +#[cfg(feature = "alloc")] +use alloc::boxed::Box; + +#[cfg(feature = "alloc")] +use alloc::vec::Vec; + +/// Types that can be serialized via `#[serde(with = "serde_bytes")]`. +pub trait Serialize { + #[allow(missing_docs)] + fn serialize(&self, serializer: S) -> Result + where + S: Serializer; +} + +impl Serialize for [u8] { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_bytes(self) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl Serialize for Vec { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_bytes(self) + } +} + +impl Serialize for Bytes { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_bytes(self) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl Serialize for ByteBuf { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_bytes(self) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a> Serialize for Cow<'a, [u8]> { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_bytes(self) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl<'a> Serialize for Cow<'a, Bytes> { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_bytes(self) + } +} + +impl<'a, T> Serialize for &'a T +where + T: ?Sized + Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + (**self).serialize(serializer) + } +} + +#[cfg(any(feature = "std", feature = "alloc"))] +impl Serialize for Box +where + T: ?Sized + Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + (**self).serialize(serializer) + } +} + +impl Serialize for Option +where + T: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + struct AsBytes(T); + + impl serde::Serialize for AsBytes + where + T: Serialize, + { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } + } + + match self { + Some(b) => serializer.serialize_some(&AsBytes(b)), + None => serializer.serialize_none(), + } + } +} -- cgit v1.2.3