serde_bytes/
bytes.rs

1use core::cmp::Ordering;
2use core::fmt::{self, Debug};
3use core::hash::{Hash, Hasher};
4use core::ops::{Deref, DerefMut};
5
6#[cfg(feature = "alloc")]
7use alloc::borrow::ToOwned;
8
9#[cfg(feature = "alloc")]
10use alloc::boxed::Box;
11
12#[cfg(any(feature = "std", feature = "alloc"))]
13use crate::ByteBuf;
14
15use serde::de::{Deserialize, Deserializer};
16use serde::ser::{Serialize, Serializer};
17
18/// Wrapper around `[u8]` to serialize and deserialize efficiently.
19///
20/// ```
21/// use std::collections::HashMap;
22/// use std::io;
23///
24/// use serde_bytes::Bytes;
25///
26/// fn print_encoded_cache() -> bincode::Result<()> {
27///     let mut cache = HashMap::new();
28///     cache.insert(3, Bytes::new(b"three"));
29///     cache.insert(2, Bytes::new(b"two"));
30///     cache.insert(1, Bytes::new(b"one"));
31///
32///     bincode::serialize_into(&mut io::stdout(), &cache)
33/// }
34/// #
35/// # fn main() {
36/// #     print_encoded_cache().unwrap();
37/// # }
38/// ```
39#[derive(Eq, Ord)]
40#[repr(transparent)]
41pub struct Bytes {
42    bytes: [u8],
43}
44
45impl Bytes {
46    /// Wrap an existing `&[u8]`.
47    pub fn new(bytes: &[u8]) -> &Self {
48        unsafe { &*(bytes as *const [u8] as *const Bytes) }
49    }
50}
51
52impl Debug for Bytes {
53    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54        Debug::fmt(&self.bytes, f)
55    }
56}
57
58impl AsRef<[u8]> for Bytes {
59    fn as_ref(&self) -> &[u8] {
60        &self.bytes
61    }
62}
63
64impl AsMut<[u8]> for Bytes {
65    fn as_mut(&mut self) -> &mut [u8] {
66        &mut self.bytes
67    }
68}
69
70impl Deref for Bytes {
71    type Target = [u8];
72
73    fn deref(&self) -> &Self::Target {
74        &self.bytes
75    }
76}
77
78impl DerefMut for Bytes {
79    fn deref_mut(&mut self) -> &mut Self::Target {
80        &mut self.bytes
81    }
82}
83
84impl<'a> From<&'a [u8]> for &'a Bytes {
85    fn from(bytes: &'a [u8]) -> Self {
86        Bytes::new(bytes)
87    }
88}
89
90#[cfg(any(feature = "std", feature = "alloc"))]
91impl ToOwned for Bytes {
92    type Owned = ByteBuf;
93
94    fn to_owned(&self) -> Self::Owned {
95        ByteBuf::from(&self.bytes)
96    }
97}
98
99#[cfg(any(feature = "std", feature = "alloc"))]
100impl From<Box<[u8]>> for Box<Bytes> {
101    fn from(bytes: Box<[u8]>) -> Self {
102        unsafe { Box::from_raw(Box::into_raw(bytes) as *mut Bytes) }
103    }
104}
105
106impl<'a> Default for &'a Bytes {
107    fn default() -> Self {
108        Bytes::new(&[])
109    }
110}
111
112#[cfg(any(feature = "std", feature = "alloc"))]
113impl Default for Box<Bytes> {
114    fn default() -> Self {
115        ByteBuf::new().into_boxed_bytes()
116    }
117}
118
119impl<Rhs> PartialEq<Rhs> for Bytes
120where
121    Rhs: ?Sized + AsRef<[u8]>,
122{
123    fn eq(&self, other: &Rhs) -> bool {
124        self.as_ref().eq(other.as_ref())
125    }
126}
127
128impl<Rhs> PartialOrd<Rhs> for Bytes
129where
130    Rhs: ?Sized + AsRef<[u8]>,
131{
132    fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> {
133        self.as_ref().partial_cmp(other.as_ref())
134    }
135}
136
137impl Hash for Bytes {
138    fn hash<H: Hasher>(&self, state: &mut H) {
139        self.bytes.hash(state);
140    }
141}
142
143impl<'a> IntoIterator for &'a Bytes {
144    type Item = &'a u8;
145    type IntoIter = <&'a [u8] as IntoIterator>::IntoIter;
146
147    fn into_iter(self) -> Self::IntoIter {
148        self.bytes.iter()
149    }
150}
151
152impl<'a> IntoIterator for &'a mut Bytes {
153    type Item = &'a mut u8;
154    type IntoIter = <&'a mut [u8] as IntoIterator>::IntoIter;
155
156    fn into_iter(self) -> Self::IntoIter {
157        self.bytes.iter_mut()
158    }
159}
160
161impl Serialize for Bytes {
162    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
163    where
164        S: Serializer,
165    {
166        serializer.serialize_bytes(&self.bytes)
167    }
168}
169
170impl<'a, 'de: 'a> Deserialize<'de> for &'a Bytes {
171    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
172    where
173        D: Deserializer<'de>,
174    {
175        // serde::Deserialize for &[u8] is already optimized, so simply forward to that.
176        Deserialize::deserialize(deserializer).map(Bytes::new)
177    }
178}