cs_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, Error, Visitor};
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 cs_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(C)]
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
84#[cfg(any(feature = "std", feature = "alloc"))]
85impl ToOwned for Bytes {
86    type Owned = ByteBuf;
87
88    fn to_owned(&self) -> Self::Owned {
89        ByteBuf::from(&self.bytes)
90    }
91}
92
93#[cfg(any(feature = "std", feature = "alloc"))]
94impl From<Box<[u8]>> for Box<Bytes> {
95    fn from(bytes: Box<[u8]>) -> Self {
96        unsafe { Box::from_raw(Box::into_raw(bytes) as *mut Bytes) }
97    }
98}
99
100impl<'a> Default for &'a Bytes {
101    fn default() -> Self {
102        Bytes::new(&[])
103    }
104}
105
106#[cfg(any(feature = "std", feature = "alloc"))]
107impl Default for Box<Bytes> {
108    fn default() -> Self {
109        ByteBuf::new().into_boxed_bytes()
110    }
111}
112
113impl<Rhs> PartialEq<Rhs> for Bytes
114where
115    Rhs: ?Sized + AsRef<[u8]>,
116{
117    fn eq(&self, other: &Rhs) -> bool {
118        self.as_ref().eq(other.as_ref())
119    }
120}
121
122impl<Rhs> PartialOrd<Rhs> for Bytes
123where
124    Rhs: ?Sized + AsRef<[u8]>,
125{
126    fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> {
127        self.as_ref().partial_cmp(other.as_ref())
128    }
129}
130
131impl Hash for Bytes {
132    fn hash<H: Hasher>(&self, state: &mut H) {
133        self.bytes.hash(state);
134    }
135}
136
137impl<'a> IntoIterator for &'a Bytes {
138    type Item = &'a u8;
139    type IntoIter = <&'a [u8] as IntoIterator>::IntoIter;
140
141    fn into_iter(self) -> Self::IntoIter {
142        self.bytes.iter()
143    }
144}
145
146impl<'a> IntoIterator for &'a mut Bytes {
147    type Item = &'a mut u8;
148    type IntoIter = <&'a mut [u8] as IntoIterator>::IntoIter;
149
150    fn into_iter(self) -> Self::IntoIter {
151        self.bytes.iter_mut()
152    }
153}
154
155impl Serialize for Bytes {
156    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
157    where
158        S: Serializer,
159    {
160        serializer.serialize_bytes(&self.bytes)
161    }
162}
163
164struct BytesVisitor;
165
166impl<'de> Visitor<'de> for BytesVisitor {
167    type Value = &'de Bytes;
168
169    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
170        formatter.write_str("a borrowed byte array")
171    }
172
173    fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
174    where
175        E: Error,
176    {
177        Ok(Bytes::new(v))
178    }
179}
180
181impl<'a, 'de: 'a> Deserialize<'de> for &'a Bytes {
182    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
183    where
184        D: Deserializer<'de>,
185    {
186        deserializer.deserialize_bytes(BytesVisitor)
187    }
188}