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