Skip to main content

ntex_bytes/
bytes.rs

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