ntex_bytes/bytes.rs
1use std::{borrow, cmp, fmt, hash, mem, ops};
2
3use crate::{buf::IntoIter, debug, storage::Storage, storage::INLINE_CAP, Buf, BytesMut};
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) inner: 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 inner: 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 inner: 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.inner.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.inner.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.inner.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 inner: 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 inner: Storage::from_slice(&self[begin..end]),
252 })
253 } else {
254 let mut ret = self.clone();
255 unsafe {
256 ret.inner.set_end(end);
257 ret.inner.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 inner: self.inner.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 inner: self.inner.split_to(at, true),
399 })
400 }
401 } else {
402 None
403 }
404 }
405
406 /// Shortens the buffer, keeping the first `len` bytes and dropping the
407 /// rest.
408 ///
409 /// If `len` is greater than the buffer's current length, this has no
410 /// effect.
411 ///
412 /// The [`split_off`] method can emulate `truncate`, but this causes the
413 /// excess bytes to be returned instead of dropped.
414 ///
415 /// # Examples
416 ///
417 /// ```
418 /// use ntex_bytes::Bytes;
419 ///
420 /// let mut buf = Bytes::from(&b"hello world"[..]);
421 /// buf.truncate(5);
422 /// assert_eq!(buf, b"hello"[..]);
423 /// ```
424 ///
425 /// [`split_off`]: #method.split_off
426 #[inline]
427 pub fn truncate(&mut self, len: usize) {
428 self.inner.truncate(len, true);
429 }
430
431 /// Shortens the buffer to `len` bytes and dropping the rest.
432 ///
433 /// This is useful if underlying buffer is larger than cuurrent bytes object.
434 ///
435 /// # Examples
436 ///
437 /// ```
438 /// use ntex_bytes::Bytes;
439 ///
440 /// let mut buf = Bytes::from(&b"hello world"[..]);
441 /// buf.trimdown();
442 /// assert_eq!(buf, b"hello world"[..]);
443 /// ```
444 #[inline]
445 pub fn trimdown(&mut self) {
446 self.inner.trimdown();
447 }
448
449 /// Clears the buffer, removing all data.
450 ///
451 /// # Examples
452 ///
453 /// ```
454 /// use ntex_bytes::Bytes;
455 ///
456 /// let mut buf = Bytes::from(&b"hello world"[..]);
457 /// buf.clear();
458 /// assert!(buf.is_empty());
459 /// ```
460 #[inline]
461 pub fn clear(&mut self) {
462 self.inner = Storage::empty();
463 }
464
465 /// Attempts to convert into a `BytesMut` handle.
466 ///
467 /// This will only succeed if there are no other outstanding references to
468 /// the underlying chunk of memory. `Bytes` handles that contain inlined
469 /// bytes will always be convertible to `BytesMut`.
470 ///
471 /// # Examples
472 ///
473 /// ```
474 /// use ntex_bytes::Bytes;
475 ///
476 /// let a = Bytes::copy_from_slice(&b"Mary had a little lamb, little lamb, little lamb..."[..]);
477 ///
478 /// // Create a shallow clone
479 /// let b = a.clone();
480 ///
481 /// // This will fail because `b` shares a reference with `a`
482 /// let a = a.try_mut().unwrap_err();
483 ///
484 /// drop(b);
485 ///
486 /// // This will succeed
487 /// let mut a = a.try_mut().unwrap();
488 ///
489 /// a[0] = b'b';
490 ///
491 /// assert_eq!(&a[..4], b"bary");
492 /// ```
493 pub fn try_mut(self) -> Result<BytesMut, Bytes> {
494 if self.inner.is_mut_safe() {
495 Ok(BytesMut { inner: self.inner })
496 } else {
497 Err(self)
498 }
499 }
500
501 /// Returns an iterator over the bytes contained by the buffer.
502 ///
503 /// # Examples
504 ///
505 /// ```
506 /// use ntex_bytes::{Buf, Bytes};
507 ///
508 /// let buf = Bytes::from(&b"abc"[..]);
509 /// let mut iter = buf.iter();
510 ///
511 /// assert_eq!(iter.next().map(|b| *b), Some(b'a'));
512 /// assert_eq!(iter.next().map(|b| *b), Some(b'b'));
513 /// assert_eq!(iter.next().map(|b| *b), Some(b'c'));
514 /// assert_eq!(iter.next(), None);
515 /// ```
516 pub fn iter(&'_ self) -> std::slice::Iter<'_, u8> {
517 self.chunk().iter()
518 }
519}
520
521impl Buf for Bytes {
522 #[inline]
523 fn remaining(&self) -> usize {
524 self.len()
525 }
526
527 #[inline]
528 fn chunk(&self) -> &[u8] {
529 self.inner.as_ref()
530 }
531
532 #[inline]
533 fn advance(&mut self, cnt: usize) {
534 assert!(cnt <= self.inner.len(), "cannot advance past `remaining`");
535 unsafe {
536 self.inner.set_start(cnt);
537 }
538 }
539}
540
541impl bytes::buf::Buf for Bytes {
542 #[inline]
543 fn remaining(&self) -> usize {
544 self.len()
545 }
546
547 #[inline]
548 fn chunk(&self) -> &[u8] {
549 self.inner.as_ref()
550 }
551
552 #[inline]
553 fn advance(&mut self, cnt: usize) {
554 assert!(cnt <= self.inner.len(), "cannot advance past `remaining`");
555 unsafe {
556 self.inner.set_start(cnt);
557 }
558 }
559}
560
561impl Clone for Bytes {
562 fn clone(&self) -> Bytes {
563 Bytes {
564 inner: self.inner.clone(),
565 }
566 }
567}
568
569impl AsRef<[u8]> for Bytes {
570 #[inline]
571 fn as_ref(&self) -> &[u8] {
572 self.inner.as_ref()
573 }
574}
575
576impl ops::Deref for Bytes {
577 type Target = [u8];
578
579 #[inline]
580 fn deref(&self) -> &[u8] {
581 self.inner.as_ref()
582 }
583}
584
585impl From<&Bytes> for Bytes {
586 fn from(src: &Bytes) -> Bytes {
587 src.clone()
588 }
589}
590
591impl From<BytesMut> for Bytes {
592 fn from(src: BytesMut) -> Bytes {
593 src.freeze()
594 }
595}
596
597impl From<Vec<u8>> for Bytes {
598 /// Convert a `Vec` into a `Bytes`
599 fn from(src: Vec<u8>) -> Bytes {
600 if src.len() <= INLINE_CAP {
601 Bytes {
602 inner: Storage::from_slice(&src),
603 }
604 } else {
605 Bytes {
606 inner: Storage::from_vec(src),
607 }
608 }
609 }
610}
611
612impl From<String> for Bytes {
613 fn from(src: String) -> Bytes {
614 if src.len() <= INLINE_CAP {
615 Bytes {
616 inner: Storage::from_slice(src.as_bytes()),
617 }
618 } else {
619 Bytes {
620 inner: Storage::from_vec(src.into_bytes()),
621 }
622 }
623 }
624}
625
626impl From<&'static [u8]> for Bytes {
627 fn from(src: &'static [u8]) -> Bytes {
628 Bytes::from_static(src)
629 }
630}
631
632impl From<&'static str> for Bytes {
633 fn from(src: &'static str) -> Bytes {
634 Bytes::from_static(src.as_bytes())
635 }
636}
637
638impl<'a, const N: usize> From<&'a [u8; N]> for Bytes {
639 fn from(src: &'a [u8; N]) -> Bytes {
640 Bytes::copy_from_slice(src)
641 }
642}
643
644impl FromIterator<u8> for Bytes {
645 fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self {
646 BytesMut::from_iter(into_iter).freeze()
647 }
648}
649
650impl<'a> FromIterator<&'a u8> for Bytes {
651 fn from_iter<T: IntoIterator<Item = &'a u8>>(into_iter: T) -> Self {
652 BytesMut::from_iter(into_iter).freeze()
653 }
654}
655
656impl Eq for Bytes {}
657
658impl PartialEq for Bytes {
659 fn eq(&self, other: &Bytes) -> bool {
660 self.inner.as_ref() == other.inner.as_ref()
661 }
662}
663
664impl PartialOrd for Bytes {
665 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
666 Some(self.cmp(other))
667 }
668}
669
670impl Ord for Bytes {
671 fn cmp(&self, other: &Bytes) -> cmp::Ordering {
672 self.inner.as_ref().cmp(other.inner.as_ref())
673 }
674}
675
676impl Default for Bytes {
677 #[inline]
678 fn default() -> Bytes {
679 Bytes::new()
680 }
681}
682
683impl fmt::Debug for Bytes {
684 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
685 fmt::Debug::fmt(&debug::BsDebug(self.inner.as_ref()), fmt)
686 }
687}
688
689impl hash::Hash for Bytes {
690 fn hash<H>(&self, state: &mut H)
691 where
692 H: hash::Hasher,
693 {
694 let s: &[u8] = self.as_ref();
695 s.hash(state);
696 }
697}
698
699impl borrow::Borrow<[u8]> for Bytes {
700 fn borrow(&self) -> &[u8] {
701 self.as_ref()
702 }
703}
704
705impl IntoIterator for Bytes {
706 type Item = u8;
707 type IntoIter = IntoIter<Bytes>;
708
709 fn into_iter(self) -> Self::IntoIter {
710 IntoIter::new(self)
711 }
712}
713
714impl<'a> IntoIterator for &'a Bytes {
715 type Item = &'a u8;
716 type IntoIter = std::slice::Iter<'a, u8>;
717
718 fn into_iter(self) -> Self::IntoIter {
719 self.as_ref().iter()
720 }
721}
722
723/*
724 *
725 * ===== PartialEq / PartialOrd =====
726 *
727 */
728
729impl PartialEq<[u8]> for Bytes {
730 fn eq(&self, other: &[u8]) -> bool {
731 self.inner.as_ref() == other
732 }
733}
734
735impl<const N: usize> PartialEq<[u8; N]> for Bytes {
736 fn eq(&self, other: &[u8; N]) -> bool {
737 self.inner.as_ref() == other.as_ref()
738 }
739}
740
741impl PartialOrd<[u8]> for Bytes {
742 fn partial_cmp(&self, other: &[u8]) -> Option<cmp::Ordering> {
743 self.inner.as_ref().partial_cmp(other)
744 }
745}
746
747impl<const N: usize> PartialOrd<[u8; N]> for Bytes {
748 fn partial_cmp(&self, other: &[u8; N]) -> Option<cmp::Ordering> {
749 self.inner.as_ref().partial_cmp(other.as_ref())
750 }
751}
752
753impl PartialEq<Bytes> for [u8] {
754 fn eq(&self, other: &Bytes) -> bool {
755 *other == *self
756 }
757}
758
759impl<const N: usize> PartialEq<Bytes> for [u8; N] {
760 fn eq(&self, other: &Bytes) -> bool {
761 *other == *self
762 }
763}
764
765impl<const N: usize> PartialEq<Bytes> for &[u8; N] {
766 fn eq(&self, other: &Bytes) -> bool {
767 *other == *self
768 }
769}
770
771impl PartialOrd<Bytes> for [u8] {
772 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
773 other.partial_cmp(self)
774 }
775}
776
777impl<const N: usize> PartialOrd<Bytes> for [u8; N] {
778 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
779 other.partial_cmp(self)
780 }
781}
782
783impl PartialEq<str> for Bytes {
784 fn eq(&self, other: &str) -> bool {
785 self.inner.as_ref() == other.as_bytes()
786 }
787}
788
789impl PartialOrd<str> for Bytes {
790 fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
791 self.inner.as_ref().partial_cmp(other.as_bytes())
792 }
793}
794
795impl PartialEq<Bytes> for str {
796 fn eq(&self, other: &Bytes) -> bool {
797 *other == *self
798 }
799}
800
801impl PartialOrd<Bytes> for str {
802 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
803 other.partial_cmp(self)
804 }
805}
806
807impl PartialEq<Vec<u8>> for Bytes {
808 fn eq(&self, other: &Vec<u8>) -> bool {
809 *self == other[..]
810 }
811}
812
813impl PartialOrd<Vec<u8>> for Bytes {
814 fn partial_cmp(&self, other: &Vec<u8>) -> Option<cmp::Ordering> {
815 self.inner.as_ref().partial_cmp(&other[..])
816 }
817}
818
819impl PartialEq<Bytes> for Vec<u8> {
820 fn eq(&self, other: &Bytes) -> bool {
821 *other == *self
822 }
823}
824
825impl PartialOrd<Bytes> for Vec<u8> {
826 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
827 other.partial_cmp(self)
828 }
829}
830
831impl PartialEq<String> for Bytes {
832 fn eq(&self, other: &String) -> bool {
833 *self == other[..]
834 }
835}
836
837impl PartialOrd<String> for Bytes {
838 fn partial_cmp(&self, other: &String) -> Option<cmp::Ordering> {
839 self.inner.as_ref().partial_cmp(other.as_bytes())
840 }
841}
842
843impl PartialEq<Bytes> for String {
844 fn eq(&self, other: &Bytes) -> bool {
845 *other == *self
846 }
847}
848
849impl PartialOrd<Bytes> for String {
850 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
851 other.partial_cmp(self)
852 }
853}
854
855impl PartialEq<Bytes> for &[u8] {
856 fn eq(&self, other: &Bytes) -> bool {
857 *other == *self
858 }
859}
860
861impl PartialOrd<Bytes> for &[u8] {
862 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
863 other.partial_cmp(self)
864 }
865}
866
867impl PartialEq<Bytes> for &str {
868 fn eq(&self, other: &Bytes) -> bool {
869 *other == *self
870 }
871}
872
873impl PartialOrd<Bytes> for &str {
874 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
875 other.partial_cmp(self)
876 }
877}
878
879impl<'a, T: ?Sized> PartialEq<&'a T> for Bytes
880where
881 Bytes: PartialEq<T>,
882{
883 fn eq(&self, other: &&'a T) -> bool {
884 *self == **other
885 }
886}
887
888impl<'a, T: ?Sized> PartialOrd<&'a T> for Bytes
889where
890 Bytes: PartialOrd<T>,
891{
892 fn partial_cmp(&self, other: &&'a T) -> Option<cmp::Ordering> {
893 self.partial_cmp(&**other)
894 }
895}
896
897impl PartialEq<BytesMut> for Bytes {
898 fn eq(&self, other: &BytesMut) -> bool {
899 other[..] == self[..]
900 }
901}
902
903#[cfg(test)]
904mod tests {
905 use std::collections::HashMap;
906
907 use super::*;
908 use crate::BufMut;
909
910 const LONG: &[u8] = b"mary had a little lamb, little lamb, little lamb, little lamb, little lamb, little lamb \
911 mary had a little lamb, little lamb, little lamb, little lamb, little lamb, little lamb \
912 mary had a little lamb, little lamb, little lamb, little lamb, little lamb, little lamb";
913
914 #[test]
915 #[allow(
916 clippy::len_zero,
917 clippy::nonminimal_bool,
918 clippy::unnecessary_fallible_conversions
919 )]
920 fn bytes() {
921 let mut b = Bytes::from(LONG.to_vec());
922 b.clear();
923 assert!(b.is_inline());
924 assert!(b.is_empty());
925 assert!(b.len() == 0);
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
941 let mut h: HashMap<Bytes, usize> = HashMap::default();
942 h.insert(b.clone(), 1);
943 assert_eq!(h.get(&b), Some(&1));
944
945 let mut b = BytesMut::try_from(LONG).unwrap();
946 assert_eq!(b, LONG);
947 assert_eq!(<BytesMut as Buf>::remaining(&b), LONG.len());
948 assert_eq!(<BytesMut as BufMut>::remaining_mut(&b), 1);
949 assert_eq!(<BytesMut as Buf>::chunk(&b), LONG);
950 <BytesMut as Buf>::advance(&mut b, 10);
951 assert_eq!(<BytesMut as Buf>::chunk(&b), &LONG[10..]);
952
953 let mut b = BytesMut::with_capacity(12);
954 <BytesMut as BufMut>::put_i8(&mut b, 1);
955 assert_eq!(b, b"\x01".as_ref());
956 <BytesMut as BufMut>::put_u8(&mut b, 2);
957 assert_eq!(b, b"\x01\x02".as_ref());
958 <BytesMut as BufMut>::put_slice(&mut b, b"12345");
959 assert_eq!(b, b"\x01\x0212345".as_ref());
960 <BytesMut as BufMut>::chunk_mut(&mut b).write_byte(0, b'1');
961 unsafe { <BytesMut as BufMut>::advance_mut(&mut b, 1) };
962 assert_eq!(b, b"\x01\x02123451".as_ref());
963 }
964}