serde_human_bytes/
bytes.rs

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