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    #[allow(clippy::should_implement_trait)]
85    pub fn into_iter(self) -> <Vec<u8> as IntoIterator>::IntoIter {
86        self.bytes.into_iter()
87    }
88}
89
90impl Debug for ByteBuf {
91    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92        Debug::fmt(&self.bytes, f)
93    }
94}
95
96impl AsRef<[u8]> for ByteBuf {
97    fn as_ref(&self) -> &[u8] {
98        &self.bytes
99    }
100}
101
102impl AsMut<[u8]> for ByteBuf {
103    fn as_mut(&mut self) -> &mut [u8] {
104        &mut self.bytes
105    }
106}
107
108impl Deref for ByteBuf {
109    type Target = Vec<u8>;
110
111    fn deref(&self) -> &Self::Target {
112        &self.bytes
113    }
114}
115
116impl DerefMut for ByteBuf {
117    fn deref_mut(&mut self) -> &mut Self::Target {
118        &mut self.bytes
119    }
120}
121
122impl Borrow<Bytes> for ByteBuf {
123    fn borrow(&self) -> &Bytes {
124        Bytes::new(&self.bytes)
125    }
126}
127
128impl BorrowMut<Bytes> for ByteBuf {
129    fn borrow_mut(&mut self) -> &mut Bytes {
130        unsafe { &mut *(&mut self.bytes as &mut [u8] as *mut [u8] as *mut Bytes) }
131    }
132}
133
134impl From<Vec<u8>> for ByteBuf {
135    fn from(bytes: Vec<u8>) -> Self {
136        ByteBuf { bytes: bytes }
137    }
138}
139
140impl<Rhs> PartialEq<Rhs> for ByteBuf
141where
142    Rhs: ?Sized + AsRef<[u8]>,
143{
144    fn eq(&self, other: &Rhs) -> bool {
145        self.as_ref().eq(other.as_ref())
146    }
147}
148
149impl<Rhs> PartialOrd<Rhs> for ByteBuf
150where
151    Rhs: ?Sized + AsRef<[u8]>,
152{
153    fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> {
154        self.as_ref().partial_cmp(other.as_ref())
155    }
156}
157
158impl Hash for ByteBuf {
159    fn hash<H: Hasher>(&self, state: &mut H) {
160        self.bytes.hash(state);
161    }
162}
163
164impl IntoIterator for ByteBuf {
165    type Item = u8;
166    type IntoIter = <Vec<u8> as IntoIterator>::IntoIter;
167
168    fn into_iter(self) -> Self::IntoIter {
169        self.bytes.into_iter()
170    }
171}
172
173impl<'a> IntoIterator for &'a ByteBuf {
174    type Item = &'a u8;
175    type IntoIter = <&'a [u8] as IntoIterator>::IntoIter;
176
177    fn into_iter(self) -> Self::IntoIter {
178        self.bytes.iter()
179    }
180}
181
182impl<'a> IntoIterator for &'a mut ByteBuf {
183    type Item = &'a mut u8;
184    type IntoIter = <&'a mut [u8] as IntoIterator>::IntoIter;
185
186    fn into_iter(self) -> Self::IntoIter {
187        self.bytes.iter_mut()
188    }
189}
190
191impl Serialize for ByteBuf {
192    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
193    where
194        S: Serializer,
195    {
196        serializer.serialize_bytes(&self.bytes)
197    }
198}
199
200struct ByteBufVisitor;
201
202impl<'de> Visitor<'de> for ByteBufVisitor {
203    type Value = ByteBuf;
204
205    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
206        formatter.write_str("byte array")
207    }
208
209    fn visit_seq<V>(self, mut visitor: V) -> Result<ByteBuf, V::Error>
210    where
211        V: SeqAccess<'de>,
212    {
213        let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096);
214        let mut bytes = Vec::with_capacity(len);
215
216        while let Some(b) = visitor.next_element()? {
217            bytes.push(b);
218        }
219
220        Ok(ByteBuf::from(bytes))
221    }
222
223    fn visit_bytes<E>(self, v: &[u8]) -> Result<ByteBuf, E>
224    where
225        E: Error,
226    {
227        Ok(ByteBuf::from(v))
228    }
229
230    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<ByteBuf, E>
231    where
232        E: Error,
233    {
234        Ok(ByteBuf::from(v))
235    }
236
237    fn visit_str<E>(self, v: &str) -> Result<ByteBuf, E>
238    where
239        E: Error,
240    {
241        Ok(ByteBuf::from(v))
242    }
243
244    fn visit_string<E>(self, v: String) -> Result<ByteBuf, E>
245    where
246        E: Error,
247    {
248        Ok(ByteBuf::from(v))
249    }
250}
251
252impl<'de> Deserialize<'de> for ByteBuf {
253    fn deserialize<D>(deserializer: D) -> Result<ByteBuf, D::Error>
254    where
255        D: Deserializer<'de>,
256    {
257        deserializer.deserialize_byte_buf(ByteBufVisitor)
258    }
259}