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}