Skip to main content

serde_bytes/
bytebuf.rs

1#[cfg(feature = "alloc")]
2use alloc::boxed::Box;
3#[cfg(feature = "alloc")]
4use alloc::string::String;
5#[cfg(feature = "alloc")]
6use alloc::vec::Vec;
7use core::{
8    borrow::{Borrow, BorrowMut},
9    cmp::{self, Ordering},
10    fmt::{self, Debug},
11    hash::{Hash, Hasher},
12    ops::{Deref, DerefMut},
13};
14
15use serde::{
16    de::{Deserialize, Deserializer, Error, SeqAccess, Visitor},
17    ser::{Serialize, Serializer},
18};
19
20use crate::Bytes;
21
22/// Wrapper around `Vec<u8>` to serialize and deserialize efficiently.
23///
24/// ```
25/// use std::collections::HashMap;
26///
27/// use serde_bytes::ByteBuf;
28///
29/// fn deserialize_bytebufs() -> serde_json::Result<()> {
30///     let example_data = br#"{"1":[111,110,101],"2":[116,119,111]}"#;
31///
32///     let map: HashMap<u32, ByteBuf> = serde_json::from_slice(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 {
137            bytes,
138        }
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}