ntex_bytes/
bytes.rs

1use std::{borrow, cmp, fmt, hash, mem, ops};
2
3use crate::{Buf, BytesMut, buf::IntoIter, debug, storage::INLINE_CAP, storage::Storage};
4
5/// A reference counted contiguous slice of memory.
6///
7/// `Bytes` is an efficient container for storing and operating on contiguous
8/// slices of memory. It is intended for use primarily in networking code, but
9/// could have applications elsewhere as well.
10///
11/// `Bytes` values facilitate zero-copy network programming by allowing multiple
12/// `Bytes` objects to point to the same underlying memory. This is managed by
13/// using a reference count to track when the memory is no longer needed and can
14/// be freed.
15///
16/// ```
17/// use ntex_bytes::Bytes;
18///
19/// let mut mem = Bytes::from(&b"Hello world"[..]);
20/// let a = mem.slice(0..5);
21///
22/// assert_eq!(a, b"Hello");
23///
24/// let b = mem.split_to(6);
25///
26/// assert_eq!(mem, b"world");
27/// assert_eq!(b, b"Hello ");
28/// ```
29///
30/// # Memory layout
31///
32/// The `Bytes` struct itself is fairly small, limited to a pointer to the
33/// memory and 4 `usize` fields used to track information about which segment of
34/// the underlying memory the `Bytes` handle has access to.
35///
36/// The memory layout looks like this:
37///
38/// ```text
39/// +-------+
40/// | Bytes |
41/// +-------+
42///  /      \_____
43/// |              \
44/// v               v
45/// +-----+------------------------------------+
46/// | Arc |         |      Data     |          |
47/// +-----+------------------------------------+
48/// ```
49///
50/// `Bytes` keeps both a pointer to the shared `Arc` containing the full memory
51/// slice and a pointer to the start of the region visible by the handle.
52/// `Bytes` also tracks the length of its view into the memory.
53///
54/// # Sharing
55///
56/// The memory itself is reference counted, and multiple `Bytes` objects may
57/// point to the same region. Each `Bytes` handle point to different sections within
58/// the memory region, and `Bytes` handle may or may not have overlapping views
59/// into the memory.
60///
61///
62/// ```text
63///
64///    Arc ptrs                   +---------+
65///    ________________________ / | Bytes 2 |
66///   /                           +---------+
67///  /          +-----------+     |         |
68/// |_________/ |  Bytes 1  |     |         |
69/// |           +-----------+     |         |
70/// |           |           | ___/ data     | tail
71/// |      data |      tail |/              |
72/// v           v           v               v
73/// +-----+---------------------------------+-----+
74/// | Arc |     |           |               |     |
75/// +-----+---------------------------------+-----+
76/// ```
77///
78/// # Mutating
79///
80/// While `Bytes` handles may potentially represent overlapping views of the
81/// underlying memory slice and may not be mutated, `BytesMut` handles are
82/// guaranteed to be the only handle able to view that slice of memory. As such,
83/// `BytesMut` handles are able to mutate the underlying memory. Note that
84/// holding a unique view to a region of memory does not mean that there are no
85/// other `Bytes` and `BytesMut` handles with disjoint views of the underlying
86/// memory.
87///
88/// # Inline bytes
89///
90/// As an optimization, when the slice referenced by a `Bytes` handle is small
91/// enough [^1]. In this case, a clone is no longer "shallow" and the data will
92/// be copied.  Converting from a `Vec` will never use inlining. `BytesMut` does
93/// not support data inlining and always allocates, but during converion to `Bytes`
94/// data from `BytesMut` could be inlined.
95///
96/// [^1]: Small enough: 31 bytes on 64 bit systems, 15 on 32 bit systems.
97///
98pub struct Bytes {
99    pub(crate) storage: Storage,
100}
101
102/*
103 *
104 * ===== Bytes =====
105 *
106 */
107
108impl Bytes {
109    /// Creates a new empty `Bytes`.
110    ///
111    /// This will not allocate and the returned `Bytes` handle will be empty.
112    ///
113    /// # Examples
114    ///
115    /// ```
116    /// use ntex_bytes::Bytes;
117    ///
118    /// let b = Bytes::new();
119    /// assert_eq!(&b[..], b"");
120    /// ```
121    #[inline]
122    pub const fn new() -> Bytes {
123        Bytes {
124            storage: Storage::empty(),
125        }
126    }
127
128    /// Creates a new `Bytes` from a static slice.
129    ///
130    /// The returned `Bytes` will point directly to the static slice. There is
131    /// no allocating or copying.
132    ///
133    /// # Examples
134    ///
135    /// ```
136    /// use ntex_bytes::Bytes;
137    ///
138    /// let b = Bytes::from_static(b"hello");
139    /// assert_eq!(&b[..], b"hello");
140    /// ```
141    #[inline]
142    pub const fn from_static(bytes: &'static [u8]) -> Bytes {
143        Bytes {
144            storage: Storage::from_static(bytes),
145        }
146    }
147
148    /// Returns the number of bytes contained in this `Bytes`.
149    ///
150    /// # Examples
151    ///
152    /// ```
153    /// use ntex_bytes::Bytes;
154    ///
155    /// let b = Bytes::from(&b"hello"[..]);
156    /// assert_eq!(b.len(), 5);
157    /// ```
158    #[inline]
159    pub fn len(&self) -> usize {
160        self.storage.len()
161    }
162
163    /// Returns true if the `Bytes` has a length of 0.
164    ///
165    /// # Examples
166    ///
167    /// ```
168    /// use ntex_bytes::Bytes;
169    ///
170    /// let b = Bytes::new();
171    /// assert!(b.is_empty());
172    /// ```
173    #[inline]
174    pub fn is_empty(&self) -> bool {
175        self.storage.is_empty()
176    }
177
178    /// Return true if the `Bytes` uses inline allocation
179    ///
180    /// # Examples
181    /// ```
182    /// use ntex_bytes::{Bytes, BytesMut};
183    ///
184    /// assert!(Bytes::from(BytesMut::from(&[0, 0, 0, 0][..])).is_inline());
185    /// assert!(Bytes::from(Vec::with_capacity(4)).is_inline());
186    /// assert!(!Bytes::from(&[0; 1024][..]).is_inline());
187    /// ```
188    pub fn is_inline(&self) -> bool {
189        self.storage.is_inline()
190    }
191
192    /// Creates `Bytes` instance from slice, by copying it.
193    pub fn copy_from_slice(data: &[u8]) -> Self {
194        Bytes {
195            storage: Storage::from_slice(data),
196        }
197    }
198
199    /// Returns a slice of self for the provided range.
200    ///
201    /// This will increment the reference count for the underlying memory and
202    /// return a new `Bytes` handle set to the slice.
203    ///
204    /// This operation is `O(1)`.
205    ///
206    /// # Examples
207    ///
208    /// ```
209    /// use ntex_bytes::Bytes;
210    ///
211    /// let a = Bytes::from(b"hello world");
212    /// let b = a.slice(2..5);
213    ///
214    /// assert_eq!(&b[..], b"llo");
215    /// assert_eq!(&b[..=1], b"ll");
216    /// assert_eq!(&b[1..=1], b"l");
217    /// ```
218    ///
219    /// # Panics
220    ///
221    /// Requires that `begin <= end` and `end <= self.len()`, otherwise slicing
222    /// will panic.
223    pub fn slice(&self, range: impl ops::RangeBounds<usize>) -> Bytes {
224        self.slice_checked(range)
225            .expect("Requires that `begin <= end` and `end <= self.len()`")
226    }
227
228    /// Returns a slice of self for the provided range.
229    ///
230    /// Does nothing if `begin <= end` or `end <= self.len()`
231    pub fn slice_checked(&self, range: impl ops::RangeBounds<usize>) -> Option<Bytes> {
232        use std::ops::Bound;
233
234        let len = self.len();
235
236        let begin = match range.start_bound() {
237            Bound::Included(&n) => n,
238            Bound::Excluded(&n) => n + 1,
239            Bound::Unbounded => 0,
240        };
241
242        let end = match range.end_bound() {
243            Bound::Included(&n) => n + 1,
244            Bound::Excluded(&n) => n,
245            Bound::Unbounded => len,
246        };
247
248        if begin <= end && end <= len {
249            if end - begin <= INLINE_CAP {
250                Some(Bytes {
251                    storage: Storage::from_slice(&self[begin..end]),
252                })
253            } else {
254                let mut ret = self.clone();
255                unsafe {
256                    ret.storage.set_end(end);
257                    ret.storage.set_start(begin);
258                }
259                Some(ret)
260            }
261        } else {
262            None
263        }
264    }
265
266    /// Returns a slice of self that is equivalent to the given `subset`.
267    ///
268    /// When processing a `Bytes` buffer with other tools, one often gets a
269    /// `&[u8]` which is in fact a slice of the `Bytes`, i.e. a subset of it.
270    /// This function turns that `&[u8]` into another `Bytes`, as if one had
271    /// called `self.slice()` with the offsets that correspond to `subset`.
272    ///
273    /// This operation is `O(1)`.
274    ///
275    /// # Examples
276    ///
277    /// ```
278    /// use ntex_bytes::Bytes;
279    ///
280    /// let bytes = Bytes::from(&b"012345678"[..]);
281    /// let as_slice = bytes.as_ref();
282    /// let subset = &as_slice[2..6];
283    /// let subslice = bytes.slice_ref(&subset);
284    /// assert_eq!(subslice, b"2345");
285    /// ```
286    ///
287    /// # Panics
288    ///
289    /// Requires that the given `sub` slice is in fact contained within the
290    /// `Bytes` buffer; otherwise this function will panic.
291    pub fn slice_ref(&self, subset: &[u8]) -> Bytes {
292        self.slice_ref_checked(subset)
293            .expect("Given `sub` slice is not contained within the `Bytes` buffer")
294    }
295
296    /// Returns a slice of self that is equivalent to the given `subset`.
297    pub fn slice_ref_checked(&self, subset: &[u8]) -> Option<Bytes> {
298        let bytes_p = self.as_ptr() as usize;
299        let bytes_len = self.len();
300
301        let sub_p = subset.as_ptr() as usize;
302        let sub_len = subset.len();
303
304        if sub_p >= bytes_p && sub_p + sub_len <= bytes_p + bytes_len {
305            let sub_offset = sub_p - bytes_p;
306            Some(self.slice(sub_offset..(sub_offset + sub_len)))
307        } else {
308            None
309        }
310    }
311
312    /// Splits the bytes into two at the given index.
313    ///
314    /// Afterwards `self` contains elements `[0, at)`, and the returned `Bytes`
315    /// contains elements `[at, len)`.
316    ///
317    /// This is an `O(1)` operation that just increases the reference count and
318    /// sets a few indices.
319    ///
320    /// # Examples
321    ///
322    /// ```
323    /// use ntex_bytes::Bytes;
324    ///
325    /// let mut a = Bytes::from(&b"hello world"[..]);
326    /// let b = a.split_off(5);
327    ///
328    /// assert_eq!(a, b"hello");
329    /// assert_eq!(b, b" world");
330    /// ```
331    ///
332    /// # Panics
333    ///
334    /// Panics if `at > self.len()`.
335    pub fn split_off(&mut self, at: usize) -> Bytes {
336        self.split_off_checked(at)
337            .expect("at value must be <= self.len()`")
338    }
339
340    /// Splits the bytes into two at the given index.
341    ///
342    /// Does nothing if `at > self.len()`
343    pub fn split_off_checked(&mut self, at: usize) -> Option<Bytes> {
344        if at <= self.len() {
345            if at == self.len() {
346                Some(Bytes::new())
347            } else if at == 0 {
348                Some(mem::take(self))
349            } else {
350                Some(Bytes {
351                    storage: self.storage.split_off(at, true),
352                })
353            }
354        } else {
355            None
356        }
357    }
358
359    /// Splits the bytes into two at the given index.
360    ///
361    /// Afterwards `self` contains elements `[at, len)`, and the returned
362    /// `Bytes` contains elements `[0, at)`.
363    ///
364    /// This is an `O(1)` operation that just increases the reference count and
365    /// sets a few indices.
366    ///
367    /// # Examples
368    ///
369    /// ```
370    /// use ntex_bytes::Bytes;
371    ///
372    /// let mut a = Bytes::from(&b"hello world"[..]);
373    /// let b = a.split_to(5);
374    ///
375    /// assert_eq!(a, b" world");
376    /// assert_eq!(b, b"hello");
377    /// ```
378    ///
379    /// # Panics
380    ///
381    /// Panics if `at > len`.
382    pub fn split_to(&mut self, at: usize) -> Bytes {
383        self.split_to_checked(at)
384            .expect("at value must be <= self.len()`")
385    }
386
387    /// Splits the bytes into two at the given index.
388    ///
389    /// Does nothing if `at > len`.
390    pub fn split_to_checked(&mut self, at: usize) -> Option<Bytes> {
391        if at <= self.len() {
392            if at == self.len() {
393                Some(mem::take(self))
394            } else if at == 0 {
395                Some(Bytes::new())
396            } else {
397                Some(Bytes {
398                    storage: self.storage.split_to(at),
399                })
400            }
401        } else {
402            None
403        }
404    }
405
406    /// Advance the internal cursor.
407    ///
408    /// Afterwards `self` contains elements `[cnt, len)`.
409    /// This is an `O(1)` operation.
410    ///
411    /// # Examples
412    ///
413    /// ```
414    /// use ntex_bytes::Bytes;
415    ///
416    /// let mut a = Bytes::copy_from_slice(&b"hello world"[..]);
417    /// a.advance_to(5);
418    ///
419    /// assert_eq!(&a[..], b" world");
420    /// ```
421    ///
422    /// # Panics
423    ///
424    /// Panics if `cnt > len`.
425    pub fn advance_to(&mut self, cnt: usize) {
426        unsafe {
427            self.storage.set_start(cnt);
428        }
429    }
430
431    /// Shortens the buffer, keeping the first `len` bytes and dropping the
432    /// rest.
433    ///
434    /// If `len` is greater than the buffer's current length, this has no
435    /// effect.
436    ///
437    /// The [`split_off`] method can emulate `truncate`, but this causes the
438    /// excess bytes to be returned instead of dropped.
439    ///
440    /// # Examples
441    ///
442    /// ```
443    /// use ntex_bytes::Bytes;
444    ///
445    /// let mut buf = Bytes::from(&b"hello world"[..]);
446    /// buf.truncate(5);
447    /// assert_eq!(buf, b"hello"[..]);
448    /// ```
449    ///
450    /// [`split_off`]: #method.split_off
451    #[inline]
452    pub fn truncate(&mut self, len: usize) {
453        self.storage.truncate(len, true);
454    }
455
456    /// Shortens the buffer to `len` bytes and dropping the rest.
457    ///
458    /// This is useful if underlying buffer is larger than cuurrent bytes object.
459    ///
460    /// # Examples
461    ///
462    /// ```
463    /// use ntex_bytes::Bytes;
464    ///
465    /// let mut buf = Bytes::from(&b"hello world"[..]);
466    /// buf.trimdown();
467    /// assert_eq!(buf, b"hello world"[..]);
468    /// ```
469    #[inline]
470    pub fn trimdown(&mut self) {
471        self.storage.trimdown();
472    }
473
474    /// Clears the buffer, removing all data.
475    ///
476    /// # Examples
477    ///
478    /// ```
479    /// use ntex_bytes::Bytes;
480    ///
481    /// let mut buf = Bytes::from(&b"hello world"[..]);
482    /// buf.clear();
483    /// assert!(buf.is_empty());
484    /// ```
485    #[inline]
486    pub fn clear(&mut self) {
487        self.storage = Storage::empty();
488    }
489
490    /// Attempts to convert into a `BytesMut` handle.
491    ///
492    /// This will only succeed if there are no other outstanding references to
493    /// the underlying chunk of memory. `Bytes` handles that contain inlined
494    /// bytes will always be convertible to `BytesMut`.
495    ///
496    /// # Examples
497    ///
498    /// ```
499    /// use ntex_bytes::Bytes;
500    ///
501    /// let a = Bytes::copy_from_slice(&b"Mary had a little lamb, little lamb, little lamb..."[..]);
502    ///
503    /// // Create a shallow clone
504    /// let b = a.clone();
505    ///
506    /// // This will fail because `b` shares a reference with `a`
507    /// let a = a.try_mut().unwrap_err();
508    ///
509    /// drop(b);
510    ///
511    /// // This will succeed
512    /// let mut a = a.try_mut().unwrap();
513    ///
514    /// a[0] = b'b';
515    ///
516    /// assert_eq!(&a[..4], b"bary");
517    /// ```
518    pub fn try_mut(self) -> Result<BytesMut, Bytes> {
519        if self.storage.is_mut_safe() {
520            Ok(BytesMut {
521                storage: self.storage,
522            })
523        } else {
524            Err(self)
525        }
526    }
527
528    /// Returns an iterator over the bytes contained by the buffer.
529    ///
530    /// # Examples
531    ///
532    /// ```
533    /// use ntex_bytes::{Buf, Bytes};
534    ///
535    /// let buf = Bytes::from(&b"abc"[..]);
536    /// let mut iter = buf.iter();
537    ///
538    /// assert_eq!(iter.next().map(|b| *b), Some(b'a'));
539    /// assert_eq!(iter.next().map(|b| *b), Some(b'b'));
540    /// assert_eq!(iter.next().map(|b| *b), Some(b'c'));
541    /// assert_eq!(iter.next(), None);
542    /// ```
543    pub fn iter(&'_ self) -> std::slice::Iter<'_, u8> {
544        self.chunk().iter()
545    }
546
547    #[inline]
548    #[doc(hidden)]
549    pub fn info(&self) -> crate::info::Info {
550        self.storage.info()
551    }
552}
553
554impl Buf for Bytes {
555    #[inline]
556    fn remaining(&self) -> usize {
557        self.len()
558    }
559
560    #[inline]
561    fn chunk(&self) -> &[u8] {
562        self.storage.as_ref()
563    }
564
565    #[inline]
566    fn advance(&mut self, cnt: usize) {
567        self.advance_to(cnt)
568    }
569}
570
571impl bytes::buf::Buf for Bytes {
572    #[inline]
573    fn remaining(&self) -> usize {
574        self.len()
575    }
576
577    #[inline]
578    fn chunk(&self) -> &[u8] {
579        self.storage.as_ref()
580    }
581
582    #[inline]
583    fn advance(&mut self, cnt: usize) {
584        self.advance_to(cnt)
585    }
586}
587
588impl Clone for Bytes {
589    fn clone(&self) -> Bytes {
590        Bytes {
591            storage: self.storage.clone(),
592        }
593    }
594}
595
596impl AsRef<[u8]> for Bytes {
597    #[inline]
598    fn as_ref(&self) -> &[u8] {
599        self.storage.as_ref()
600    }
601}
602
603impl ops::Deref for Bytes {
604    type Target = [u8];
605
606    #[inline]
607    fn deref(&self) -> &[u8] {
608        self.storage.as_ref()
609    }
610}
611
612impl From<&Bytes> for Bytes {
613    fn from(src: &Bytes) -> Bytes {
614        src.clone()
615    }
616}
617
618impl From<BytesMut> for Bytes {
619    fn from(src: BytesMut) -> Bytes {
620        src.freeze()
621    }
622}
623
624impl From<Vec<u8>> for Bytes {
625    /// Convert a `Vec` into a `Bytes`
626    fn from(src: Vec<u8>) -> Bytes {
627        if src.len() <= INLINE_CAP {
628            Bytes {
629                storage: Storage::from_slice(&src),
630            }
631        } else {
632            Bytes {
633                storage: Storage::from_vec(src),
634            }
635        }
636    }
637}
638
639impl From<String> for Bytes {
640    fn from(src: String) -> Bytes {
641        if src.len() <= INLINE_CAP {
642            Bytes {
643                storage: Storage::from_slice(src.as_bytes()),
644            }
645        } else {
646            Bytes {
647                storage: Storage::from_vec(src.into_bytes()),
648            }
649        }
650    }
651}
652
653impl From<&'static [u8]> for Bytes {
654    fn from(src: &'static [u8]) -> Bytes {
655        Bytes::from_static(src)
656    }
657}
658
659impl From<&'static str> for Bytes {
660    fn from(src: &'static str) -> Bytes {
661        Bytes::from_static(src.as_bytes())
662    }
663}
664
665impl<'a, const N: usize> From<&'a [u8; N]> for Bytes {
666    fn from(src: &'a [u8; N]) -> Bytes {
667        Bytes::copy_from_slice(src)
668    }
669}
670
671impl FromIterator<u8> for Bytes {
672    fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self {
673        BytesMut::from_iter(into_iter).freeze()
674    }
675}
676
677impl<'a> FromIterator<&'a u8> for Bytes {
678    fn from_iter<T: IntoIterator<Item = &'a u8>>(into_iter: T) -> Self {
679        BytesMut::from_iter(into_iter).freeze()
680    }
681}
682
683impl Eq for Bytes {}
684
685impl PartialEq for Bytes {
686    fn eq(&self, other: &Bytes) -> bool {
687        self.storage.as_ref() == other.storage.as_ref()
688    }
689}
690
691impl PartialOrd for Bytes {
692    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
693        Some(self.cmp(other))
694    }
695}
696
697impl Ord for Bytes {
698    fn cmp(&self, other: &Bytes) -> cmp::Ordering {
699        self.storage.as_ref().cmp(other.storage.as_ref())
700    }
701}
702
703impl Default for Bytes {
704    #[inline]
705    fn default() -> Bytes {
706        Bytes::new()
707    }
708}
709
710impl fmt::Debug for Bytes {
711    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
712        fmt::Debug::fmt(&debug::BsDebug(self.storage.as_ref()), fmt)
713    }
714}
715
716impl hash::Hash for Bytes {
717    fn hash<H>(&self, state: &mut H)
718    where
719        H: hash::Hasher,
720    {
721        let s: &[u8] = self.as_ref();
722        s.hash(state);
723    }
724}
725
726impl borrow::Borrow<[u8]> for Bytes {
727    fn borrow(&self) -> &[u8] {
728        self.as_ref()
729    }
730}
731
732impl IntoIterator for Bytes {
733    type Item = u8;
734    type IntoIter = IntoIter<Bytes>;
735
736    fn into_iter(self) -> Self::IntoIter {
737        IntoIter::new(self)
738    }
739}
740
741impl<'a> IntoIterator for &'a Bytes {
742    type Item = &'a u8;
743    type IntoIter = std::slice::Iter<'a, u8>;
744
745    fn into_iter(self) -> Self::IntoIter {
746        self.as_ref().iter()
747    }
748}
749
750/*
751 *
752 * ===== PartialEq / PartialOrd =====
753 *
754 */
755
756impl PartialEq<[u8]> for Bytes {
757    fn eq(&self, other: &[u8]) -> bool {
758        self.storage.as_ref() == other
759    }
760}
761
762impl<const N: usize> PartialEq<[u8; N]> for Bytes {
763    fn eq(&self, other: &[u8; N]) -> bool {
764        self.storage.as_ref() == other.as_ref()
765    }
766}
767
768impl PartialOrd<[u8]> for Bytes {
769    fn partial_cmp(&self, other: &[u8]) -> Option<cmp::Ordering> {
770        self.storage.as_ref().partial_cmp(other)
771    }
772}
773
774impl<const N: usize> PartialOrd<[u8; N]> for Bytes {
775    fn partial_cmp(&self, other: &[u8; N]) -> Option<cmp::Ordering> {
776        self.storage.as_ref().partial_cmp(other.as_ref())
777    }
778}
779
780impl PartialEq<Bytes> for [u8] {
781    fn eq(&self, other: &Bytes) -> bool {
782        *other == *self
783    }
784}
785
786impl<const N: usize> PartialEq<Bytes> for [u8; N] {
787    fn eq(&self, other: &Bytes) -> bool {
788        *other == *self
789    }
790}
791
792impl<const N: usize> PartialEq<Bytes> for &[u8; N] {
793    fn eq(&self, other: &Bytes) -> bool {
794        *other == *self
795    }
796}
797
798impl PartialOrd<Bytes> for [u8] {
799    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
800        other.partial_cmp(self)
801    }
802}
803
804impl<const N: usize> PartialOrd<Bytes> for [u8; N] {
805    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
806        other.partial_cmp(self)
807    }
808}
809
810impl PartialEq<str> for Bytes {
811    fn eq(&self, other: &str) -> bool {
812        self.storage.as_ref() == other.as_bytes()
813    }
814}
815
816impl PartialOrd<str> for Bytes {
817    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
818        self.storage.as_ref().partial_cmp(other.as_bytes())
819    }
820}
821
822impl PartialEq<Bytes> for str {
823    fn eq(&self, other: &Bytes) -> bool {
824        *other == *self
825    }
826}
827
828impl PartialOrd<Bytes> for str {
829    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
830        other.partial_cmp(self)
831    }
832}
833
834impl PartialEq<Vec<u8>> for Bytes {
835    fn eq(&self, other: &Vec<u8>) -> bool {
836        *self == other[..]
837    }
838}
839
840impl PartialOrd<Vec<u8>> for Bytes {
841    fn partial_cmp(&self, other: &Vec<u8>) -> Option<cmp::Ordering> {
842        self.storage.as_ref().partial_cmp(&other[..])
843    }
844}
845
846impl PartialEq<Bytes> for Vec<u8> {
847    fn eq(&self, other: &Bytes) -> bool {
848        *other == *self
849    }
850}
851
852impl PartialOrd<Bytes> for Vec<u8> {
853    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
854        other.partial_cmp(self)
855    }
856}
857
858impl PartialEq<String> for Bytes {
859    fn eq(&self, other: &String) -> bool {
860        *self == other[..]
861    }
862}
863
864impl PartialOrd<String> for Bytes {
865    fn partial_cmp(&self, other: &String) -> Option<cmp::Ordering> {
866        self.storage.as_ref().partial_cmp(other.as_bytes())
867    }
868}
869
870impl PartialEq<Bytes> for String {
871    fn eq(&self, other: &Bytes) -> bool {
872        *other == *self
873    }
874}
875
876impl PartialOrd<Bytes> for String {
877    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
878        other.partial_cmp(self)
879    }
880}
881
882impl PartialEq<Bytes> for &[u8] {
883    fn eq(&self, other: &Bytes) -> bool {
884        *other == *self
885    }
886}
887
888impl PartialOrd<Bytes> for &[u8] {
889    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
890        other.partial_cmp(self)
891    }
892}
893
894impl PartialEq<Bytes> for &str {
895    fn eq(&self, other: &Bytes) -> bool {
896        *other == *self
897    }
898}
899
900impl PartialOrd<Bytes> for &str {
901    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
902        other.partial_cmp(self)
903    }
904}
905
906impl<'a, T: ?Sized> PartialEq<&'a T> for Bytes
907where
908    Bytes: PartialEq<T>,
909{
910    fn eq(&self, other: &&'a T) -> bool {
911        *self == **other
912    }
913}
914
915impl<'a, T: ?Sized> PartialOrd<&'a T> for Bytes
916where
917    Bytes: PartialOrd<T>,
918{
919    fn partial_cmp(&self, other: &&'a T) -> Option<cmp::Ordering> {
920        self.partial_cmp(&**other)
921    }
922}
923
924impl PartialEq<BytesMut> for Bytes {
925    fn eq(&self, other: &BytesMut) -> bool {
926        other[..] == self[..]
927    }
928}
929
930#[cfg(test)]
931mod tests {
932    use std::collections::HashMap;
933
934    use super::*;
935    use crate::BufMut;
936
937    const LONG: &[u8] = b"mary had a little lamb, little lamb, little lamb, little lamb, little lamb, little lamb \
938        mary had a little lamb, little lamb, little lamb, little lamb, little lamb, little lamb \
939        mary had a little lamb, little lamb, little lamb, little lamb, little lamb, little lamb";
940
941    #[test]
942    #[allow(
943        clippy::len_zero,
944        clippy::nonminimal_bool,
945        clippy::unnecessary_fallible_conversions
946    )]
947    fn bytes() {
948        let mut b = Bytes::from(LONG.to_vec());
949        b.clear();
950        assert!(b.is_inline());
951        assert!(b.is_empty());
952        assert!(b.len() == 0);
953
954        let b = Bytes::from(&Bytes::from(LONG));
955        assert_eq!(b, LONG);
956
957        let b = Bytes::from(BytesMut::from(LONG));
958        assert_eq!(b, LONG);
959
960        let mut b: Bytes = BytesMut::try_from(b).unwrap().freeze();
961        assert_eq!(b, LONG);
962        assert!(!(b > b));
963        assert_eq!(<Bytes as Buf>::remaining(&b), LONG.len());
964        assert_eq!(<Bytes as Buf>::chunk(&b), LONG);
965        <Bytes as Buf>::advance(&mut b, 10);
966        assert_eq!(Buf::chunk(&b), &LONG[10..]);
967
968        let mut h: HashMap<Bytes, usize> = HashMap::default();
969        h.insert(b.clone(), 1);
970        assert_eq!(h.get(&b), Some(&1));
971
972        let mut b = BytesMut::try_from(LONG).unwrap();
973        assert_eq!(b, LONG);
974        assert_eq!(<BytesMut as Buf>::remaining(&b), LONG.len());
975        assert_eq!(<BytesMut as BufMut>::remaining_mut(&b), 0);
976        assert_eq!(<BytesMut as Buf>::chunk(&b), LONG);
977        <BytesMut as Buf>::advance(&mut b, 10);
978        assert_eq!(<BytesMut as Buf>::chunk(&b), &LONG[10..]);
979
980        let mut b = BytesMut::with_capacity(12);
981        <BytesMut as BufMut>::put_i8(&mut b, 1);
982        assert_eq!(b, b"\x01".as_ref());
983        <BytesMut as BufMut>::put_u8(&mut b, 2);
984        assert_eq!(b, b"\x01\x02".as_ref());
985        <BytesMut as BufMut>::put_slice(&mut b, b"12345");
986        assert_eq!(b, b"\x01\x0212345".as_ref());
987        <BytesMut as BufMut>::chunk_mut(&mut b).write_byte(0, b'1');
988        unsafe { <BytesMut as BufMut>::advance_mut(&mut b, 1) };
989        assert_eq!(b, b"\x01\x02123451".as_ref());
990    }
991}