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