lifetimed_bytes/
lib.rs

1#![no_std]
2
3extern crate alloc;
4
5use alloc::{string::String, vec::Vec};
6pub use bytes::{Buf, BufMut, BytesMut};
7use core::{
8    borrow::Borrow,
9    cmp,
10    fmt::{self, Debug},
11    iter::FromIterator,
12    marker::PhantomData,
13    mem::transmute,
14    ops::{Deref, RangeBounds},
15};
16
17#[derive(Clone, Default, Hash)]
18pub struct Bytes<'b> {
19    inner: bytes::Bytes,
20    _marker: PhantomData<&'b ()>,
21}
22
23impl<'b> Bytes<'b> {
24    pub const fn new() -> Self {
25        Self {
26            inner: bytes::Bytes::new(),
27            _marker: PhantomData,
28        }
29    }
30
31    pub fn len(&self) -> usize {
32        self.inner.len()
33    }
34
35    pub fn is_empty(&self) -> bool {
36        self.len() == 0
37    }
38
39    pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
40        self.inner.slice(range).into()
41    }
42
43    pub fn slice_ref(&self, subset: &[u8]) -> Self {
44        self.inner.slice_ref(subset).into()
45    }
46
47    #[must_use = "consider Bytes::truncate if you don't need the other half"]
48    pub fn split_off(&mut self, at: usize) -> Self {
49        self.inner.split_off(at).into()
50    }
51
52    #[must_use = "consider Bytes::advance if you don't need the other half"]
53    pub fn split_to(&mut self, at: usize) -> Self {
54        self.inner.split_to(at).into()
55    }
56
57    #[inline]
58    pub fn truncate(&mut self, len: usize) {
59        self.inner.truncate(len)
60    }
61
62    #[inline]
63    pub fn clear(&mut self) {
64        self.inner.clear()
65    }
66
67    fn as_slice(&'b self) -> &'b [u8] {
68        self.inner.borrow()
69    }
70}
71
72impl<'b> Buf for Bytes<'b> {
73    fn remaining(&self) -> usize {
74        self.inner.remaining()
75    }
76
77    fn chunk(&self) -> &[u8] {
78        self.as_slice()
79    }
80
81    fn advance(&mut self, cnt: usize) {
82        self.inner.advance(cnt)
83    }
84}
85
86impl<'b> Debug for Bytes<'b> {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        self.inner.fmt(f)
89    }
90}
91
92impl<'b> Deref for Bytes<'b> {
93    type Target = [u8];
94
95    fn deref(&self) -> &Self::Target {
96        self.inner.deref()
97    }
98}
99
100impl<'b> AsRef<[u8]> for Bytes<'b> {
101    fn as_ref(&self) -> &[u8] {
102        self.inner.as_ref()
103    }
104}
105
106impl<'b> Borrow<[u8]> for Bytes<'b> {
107    fn borrow(&self) -> &[u8] {
108        self.as_slice()
109    }
110}
111
112impl<'b> From<&'b [u8]> for Bytes<'b> {
113    fn from(raw: &'b [u8]) -> Self {
114        // SAFETY: normally unsound, but we just move the lifetime from slice to struct itself
115        let s = unsafe { transmute(raw) };
116        Bytes {
117            inner: bytes::Bytes::from_static(s),
118            _marker: PhantomData,
119        }
120    }
121}
122
123impl<'b, const N: usize> From<&'b [u8; N]> for Bytes<'b> {
124    fn from(raw: &'b [u8; N]) -> Self {
125        (raw as &[u8]).into()
126    }
127}
128
129impl<'b> From<&'b str> for Bytes<'b> {
130    fn from(s: &'b str) -> Self {
131        s.as_bytes().into()
132    }
133}
134
135impl<'b> From<bytes::Bytes> for Bytes<'b> {
136    fn from(inner: bytes::Bytes) -> Self {
137        Self {
138            inner,
139            _marker: PhantomData,
140        }
141    }
142}
143
144impl<'b> From<Vec<u8>> for Bytes<'b> {
145    fn from(v: Vec<u8>) -> Self {
146        bytes::Bytes::from(v).into()
147    }
148}
149
150impl From<Bytes<'static>> for bytes::Bytes {
151    fn from(l: Bytes<'static>) -> Self {
152        l.inner
153    }
154}
155
156impl<'b> FromIterator<u8> for Bytes<'b> {
157    fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self {
158        bytes::Bytes::from_iter(into_iter).into()
159    }
160}
161
162pub struct IntoIter<'b, T> {
163    inner: bytes::buf::IntoIter<T>,
164    _marker: PhantomData<&'b ()>,
165}
166
167impl<'b> Iterator for IntoIter<'b, bytes::Bytes> {
168    type Item = u8;
169
170    fn next(&mut self) -> Option<u8> {
171        self.inner.next()
172    }
173
174    fn size_hint(&self) -> (usize, Option<usize>) {
175        self.inner.size_hint()
176    }
177}
178
179impl<'b> ExactSizeIterator for IntoIter<'b, bytes::Bytes> {}
180
181impl<'b> IntoIterator for Bytes<'b> {
182    type Item = u8;
183    type IntoIter = IntoIter<'b, bytes::Bytes>;
184
185    fn into_iter(self) -> Self::IntoIter {
186        IntoIter {
187            inner: self.inner.into_iter(),
188            _marker: PhantomData,
189        }
190    }
191}
192
193macro_rules! forward_impls {
194    ($t:ty) => {
195        impl<'b> PartialEq<$t> for Bytes<'b> {
196            fn eq(&self, other: &$t) -> bool {
197                PartialEq::eq(&self.inner, other)
198            }
199        }
200
201        impl<'b> PartialEq<Bytes<'b>> for $t {
202            fn eq(&self, other: &Bytes<'b>) -> bool {
203                PartialEq::eq(self, &other.inner)
204            }
205        }
206
207        impl<'b> PartialOrd<$t> for Bytes<'b> {
208            fn partial_cmp(&self, other: &$t) -> Option<cmp::Ordering> {
209                PartialOrd::partial_cmp(&self.inner, other)
210            }
211        }
212
213        impl<'b> PartialOrd<Bytes<'b>> for $t {
214            fn partial_cmp(&self, other: &Bytes<'b>) -> Option<cmp::Ordering> {
215                PartialOrd::partial_cmp(self, &other.inner)
216            }
217        }
218    };
219}
220
221forward_impls!(bytes::Bytes);
222forward_impls!([u8]);
223forward_impls!(str);
224forward_impls!(Vec<u8>);
225forward_impls!(String);
226
227impl<'a, 'b> PartialEq<Bytes<'a>> for Bytes<'b> {
228    fn eq(&self, other: &Bytes<'a>) -> bool {
229        PartialEq::eq(&self.inner, other)
230    }
231}
232
233impl<'a, 'b> PartialOrd<Bytes<'a>> for Bytes<'b> {
234    fn partial_cmp(&self, other: &Bytes<'a>) -> Option<cmp::Ordering> {
235        PartialOrd::partial_cmp(&self.inner, other)
236    }
237}
238
239impl<'b> PartialEq<Bytes<'b>> for &[u8] {
240    fn eq(&self, other: &Bytes<'b>) -> bool {
241        PartialEq::eq(self, &other.inner)
242    }
243}
244
245impl<'b> PartialOrd<Bytes<'b>> for &[u8] {
246    fn partial_cmp(&self, other: &Bytes<'b>) -> Option<cmp::Ordering> {
247        PartialOrd::partial_cmp(self, &other.inner)
248    }
249}
250
251impl<'b, const N: usize> PartialEq<Bytes<'b>> for [u8; N] {
252    fn eq(&self, other: &Bytes<'b>) -> bool {
253        PartialEq::eq(self as &[u8], &other.inner)
254    }
255}
256
257impl<'b, const N: usize> PartialOrd<Bytes<'b>> for [u8; N] {
258    fn partial_cmp(&self, other: &Bytes<'b>) -> Option<cmp::Ordering> {
259        PartialOrd::partial_cmp(self as &[u8], &other.inner)
260    }
261}
262
263impl<'b, const N: usize> PartialEq<[u8; N]> for Bytes<'b> {
264    fn eq(&self, other: &[u8; N]) -> bool {
265        PartialEq::eq(&self.inner, other as &[u8])
266    }
267}
268
269impl<'b, const N: usize> PartialOrd<[u8; N]> for Bytes<'b> {
270    fn partial_cmp(&self, other: &[u8; N]) -> Option<cmp::Ordering> {
271        PartialOrd::partial_cmp(&self.inner, other as &[u8])
272    }
273}
274
275impl<'b> PartialEq<Bytes<'b>> for &str {
276    fn eq(&self, other: &Bytes<'b>) -> bool {
277        PartialEq::eq(self, &other.inner)
278    }
279}
280
281impl<'b> PartialOrd<Bytes<'b>> for &str {
282    fn partial_cmp(&self, other: &Bytes<'b>) -> Option<cmp::Ordering> {
283        PartialOrd::partial_cmp(self, &other.inner)
284    }
285}
286
287impl<'a, 'b, T: ?Sized> PartialEq<&'a T> for Bytes<'b>
288where
289    Bytes<'b>: PartialEq<T>,
290{
291    fn eq(&self, other: &&'a T) -> bool {
292        *self == **other
293    }
294}
295
296impl<'a, 'b, T: ?Sized> PartialOrd<&'a T> for Bytes<'b>
297where
298    Bytes<'b>: PartialOrd<T>,
299{
300    fn partial_cmp(&self, other: &&'a T) -> Option<cmp::Ordering> {
301        self.partial_cmp(&**other)
302    }
303}
304
305impl<'b> Eq for Bytes<'b> {}
306impl<'b> Ord for Bytes<'b> {
307    fn cmp(&self, other: &Self) -> cmp::Ordering {
308        self.inner.cmp(&other.inner)
309    }
310}
311
312impl<'b> From<alloc::borrow::Cow<'b, [u8]>> for Bytes<'b> {
313    fn from(v: alloc::borrow::Cow<'b, [u8]>) -> Self {
314        match v {
315            alloc::borrow::Cow::Borrowed(b) => Self::from(b),
316            alloc::borrow::Cow::Owned(b) => Self::from(b),
317        }
318    }
319}
320
321#[cfg(test)]
322pub mod tests {
323    #[test]
324    fn ui() {
325        let t = trybuild::TestCases::new();
326        t.compile_fail("tests/ui/*.rs");
327    }
328}