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