serde_bytes/
bytebuf.rs

1use core::borrow::{Borrow, BorrowMut};
2use core::cmp::{self, Ordering};
3use core::fmt::{self, Debug};
4use core::hash::{Hash, Hasher};
5use core::ops::{Deref, DerefMut};
6
7#[cfg(feature = "alloc")]
8use alloc::boxed::Box;
9#[cfg(feature = "alloc")]
10use alloc::string::String;
11#[cfg(feature = "alloc")]
12use alloc::vec::Vec;
13
14use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor};
15use serde::ser::{Serialize, Serializer};
16
17use crate::Bytes;
18
19/// Wrapper around `Vec<u8>` to serialize and deserialize efficiently.
20///
21/// ```
22/// use std::collections::HashMap;
23/// use std::io;
24///
25/// use serde_bytes::ByteBuf;
26///
27/// fn deserialize_bytebufs() -> bincode::Result<()> {
28///     let example_data = [
29///         2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 116,
30///         119, 111, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 111, 110, 101];
31///
32///     let map: HashMap<u32, ByteBuf> = bincode::deserialize(&example_data[..])?;
33///
34///     println!("{:?}", map);
35///
36///     Ok(())
37/// }
38/// #
39/// # fn main() {
40/// #     deserialize_bytebufs().unwrap();
41/// # }
42/// ```
43#[derive(Clone, Default, Eq, Ord)]
44pub struct ByteBuf {
45    bytes: Vec<u8>,
46}
47
48impl ByteBuf {
49    /// Construct a new, empty `ByteBuf`.
50    pub fn new() -> Self {
51        ByteBuf::from(Vec::new())
52    }
53
54    /// Construct a new, empty `ByteBuf` with the specified capacity.
55    pub fn with_capacity(cap: usize) -> Self {
56        ByteBuf::from(Vec::with_capacity(cap))
57    }
58
59    /// Wrap existing bytes in a `ByteBuf`.
60    pub fn from<T: Into<Vec<u8>>>(bytes: T) -> Self {
61        ByteBuf {
62            bytes: bytes.into(),
63        }
64    }
65
66    /// Unwrap the vector of byte underlying this `ByteBuf`.
67    pub fn into_vec(self) -> Vec<u8> {
68        self.bytes
69    }
70
71    #[allow(missing_docs)]
72    pub fn into_boxed_bytes(self) -> Box<Bytes> {
73        self.bytes.into_boxed_slice().into()
74    }
75
76    // This would hit "cannot move out of borrowed content" if invoked through
77    // the Deref impl; make it just work.
78    #[doc(hidden)]
79    pub fn into_boxed_slice(self) -> Box<[u8]> {
80        self.bytes.into_boxed_slice()
81    }
82
83    #[doc(hidden)]
84    pub fn into_iter(self) -> <Vec<u8> as IntoIterator>::IntoIter {
85        self.bytes.into_iter()
86    }
87}
88
89impl Debug for ByteBuf {
90    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91        Debug::fmt(&self.bytes, f)
92    }
93}
94
95impl AsRef<[u8]> for ByteBuf {
96    fn as_ref(&self) -> &[u8] {
97        &self.bytes
98    }
99}
100
101impl AsMut<[u8]> for ByteBuf {
102    fn as_mut(&mut self) -> &mut [u8] {
103        &mut self.bytes
104    }
105}
106
107impl Deref for ByteBuf {
108    type Target = Vec<u8>;
109
110    fn deref(&self) -> &Self::Target {
111        &self.bytes
112    }
113}
114
115impl DerefMut for ByteBuf {
116    fn deref_mut(&mut self) -> &mut Self::Target {
117        &mut self.bytes
118    }
119}
120
121impl Borrow<Bytes> for ByteBuf {
122    fn borrow(&self) -> &Bytes {
123        Bytes::new(&self.bytes)
124    }
125}
126
127impl BorrowMut<Bytes> for ByteBuf {
128    fn borrow_mut(&mut self) -> &mut Bytes {
129        unsafe { &mut *(&mut self.bytes as &mut [u8] as *mut [u8] as *mut Bytes) }
130    }
131}
132
133impl<Rhs> PartialEq<Rhs> for ByteBuf
134where
135    Rhs: ?Sized + AsRef<[u8]>,
136{
137    fn eq(&self, other: &Rhs) -> bool {
138        self.as_ref().eq(other.as_ref())
139    }
140}
141
142impl<Rhs> PartialOrd<Rhs> for ByteBuf
143where
144    Rhs: ?Sized + AsRef<[u8]>,
145{
146    fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> {
147        self.as_ref().partial_cmp(other.as_ref())
148    }
149}
150
151impl Hash for ByteBuf {
152    fn hash<H: Hasher>(&self, state: &mut H) {
153        self.bytes.hash(state);
154    }
155}
156
157impl IntoIterator for ByteBuf {
158    type Item = u8;
159    type IntoIter = <Vec<u8> as IntoIterator>::IntoIter;
160
161    fn into_iter(self) -> Self::IntoIter {
162        self.bytes.into_iter()
163    }
164}
165
166impl<'a> IntoIterator for &'a ByteBuf {
167    type Item = &'a u8;
168    type IntoIter = <&'a [u8] as IntoIterator>::IntoIter;
169
170    fn into_iter(self) -> Self::IntoIter {
171        self.bytes.iter()
172    }
173}
174
175impl<'a> IntoIterator for &'a mut ByteBuf {
176    type Item = &'a mut u8;
177    type IntoIter = <&'a mut [u8] as IntoIterator>::IntoIter;
178
179    fn into_iter(self) -> Self::IntoIter {
180        self.bytes.iter_mut()
181    }
182}
183
184impl Serialize for ByteBuf {
185    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
186    where
187        S: Serializer,
188    {
189        serializer.serialize_bytes(&self.bytes)
190    }
191}
192
193struct ByteBufVisitor;
194
195impl<'de> Visitor<'de> for ByteBufVisitor {
196    type Value = ByteBuf;
197
198    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
199        formatter.write_str("byte array")
200    }
201
202    fn visit_seq<V>(self, mut visitor: V) -> Result<ByteBuf, V::Error>
203    where
204        V: SeqAccess<'de>,
205    {
206        let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096);
207        let mut values = Vec::with_capacity(len);
208
209        while let Some(value) = visitor.next_element()? {
210            values.push(value);
211        }
212
213        Ok(ByteBuf::from(values))
214    }
215
216    fn visit_bytes<E>(self, v: &[u8]) -> Result<ByteBuf, E>
217    where
218        E: Error,
219    {
220        Ok(ByteBuf::from(v))
221    }
222
223    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<ByteBuf, E>
224    where
225        E: Error,
226    {
227        Ok(ByteBuf::from(v))
228    }
229
230    fn visit_str<E>(self, v: &str) -> Result<ByteBuf, E>
231    where
232        E: Error,
233    {
234        Ok(ByteBuf::from(v))
235    }
236
237    fn visit_string<E>(self, v: String) -> Result<ByteBuf, E>
238    where
239        E: Error,
240    {
241        Ok(ByteBuf::from(v))
242    }
243}
244
245impl<'de> Deserialize<'de> for ByteBuf {
246    fn deserialize<D>(deserializer: D) -> Result<ByteBuf, D::Error>
247    where
248        D: Deserializer<'de>,
249    {
250        deserializer.deserialize_byte_buf(ByteBufVisitor)
251    }
252}