diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/rust/serde_bytes/src/bytebuf.rs | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/serde_bytes/src/bytebuf.rs')
-rw-r--r-- | third_party/rust/serde_bytes/src/bytebuf.rs | 253 |
1 files changed, 253 insertions, 0 deletions
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<u8>` 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<u32, ByteBuf> = bincode::deserialize(&example_data[..])?; +/// +/// println!("{:?}", map); +/// +/// Ok(()) +/// } +/// # +/// # fn main() { +/// # deserialize_bytebufs().unwrap(); +/// # } +/// ``` +#[derive(Clone, Default, Eq, Ord)] +pub struct ByteBuf { + bytes: Vec<u8>, +} + +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<T: Into<Vec<u8>>>(bytes: T) -> Self { + ByteBuf { + bytes: bytes.into(), + } + } + + /// Unwrap the vector of byte underlying this `ByteBuf`. + pub fn into_vec(self) -> Vec<u8> { + self.bytes + } + + #[allow(missing_docs)] + pub fn into_boxed_bytes(self) -> Box<Bytes> { + 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) -> <Vec<u8> 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<u8>; + + fn deref(&self) -> &Self::Target { + &self.bytes + } +} + +impl DerefMut for ByteBuf { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.bytes + } +} + +impl Borrow<Bytes> for ByteBuf { + fn borrow(&self) -> &Bytes { + Bytes::new(&self.bytes) + } +} + +impl BorrowMut<Bytes> for ByteBuf { + fn borrow_mut(&mut self) -> &mut Bytes { + unsafe { &mut *(&mut self.bytes as &mut [u8] as *mut [u8] as *mut Bytes) } + } +} + +impl<Rhs> PartialEq<Rhs> for ByteBuf +where + Rhs: ?Sized + AsRef<[u8]>, +{ + fn eq(&self, other: &Rhs) -> bool { + self.as_ref().eq(other.as_ref()) + } +} + +impl<Rhs> PartialOrd<Rhs> for ByteBuf +where + Rhs: ?Sized + AsRef<[u8]>, +{ + fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> { + self.as_ref().partial_cmp(other.as_ref()) + } +} + +impl Hash for ByteBuf { + fn hash<H: Hasher>(&self, state: &mut H) { + self.bytes.hash(state); + } +} + +impl IntoIterator for ByteBuf { + type Item = u8; + type IntoIter = <Vec<u8> 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<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + 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<V>(self, mut visitor: V) -> Result<ByteBuf, V::Error> + 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<E>(self, v: &[u8]) -> Result<ByteBuf, E> + where + E: Error, + { + Ok(ByteBuf::from(v)) + } + + fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<ByteBuf, E> + where + E: Error, + { + Ok(ByteBuf::from(v)) + } + + fn visit_str<E>(self, v: &str) -> Result<ByteBuf, E> + where + E: Error, + { + Ok(ByteBuf::from(v)) + } + + fn visit_string<E>(self, v: String) -> Result<ByteBuf, E> + where + E: Error, + { + Ok(ByteBuf::from(v)) + } +} + +impl<'de> Deserialize<'de> for ByteBuf { + fn deserialize<D>(deserializer: D) -> Result<ByteBuf, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_byte_buf(ByteBufVisitor) + } +} |