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, 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.storage.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.storage.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.storage = 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.storage.is_mut_safe() {
495 Ok(BytesMut {
496 storage: self.storage,
497 })
498 } else {
499 Err(self)
500 }
501 }
502
503 /// Returns an iterator over the bytes contained by the buffer.
504 ///
505 /// # Examples
506 ///
507 /// ```
508 /// use ntex_bytes::{Buf, Bytes};
509 ///
510 /// let buf = Bytes::from(&b"abc"[..]);
511 /// let mut iter = buf.iter();
512 ///
513 /// assert_eq!(iter.next().map(|b| *b), Some(b'a'));
514 /// assert_eq!(iter.next().map(|b| *b), Some(b'b'));
515 /// assert_eq!(iter.next().map(|b| *b), Some(b'c'));
516 /// assert_eq!(iter.next(), None);
517 /// ```
518 pub fn iter(&'_ self) -> std::slice::Iter<'_, u8> {
519 self.chunk().iter()
520 }
521
522 #[inline]
523 #[doc(hidden)]
524 pub fn info(&self) -> crate::info::Info {
525 self.storage.info()
526 }
527}
528
529impl Buf for Bytes {
530 #[inline]
531 fn remaining(&self) -> usize {
532 self.len()
533 }
534
535 #[inline]
536 fn chunk(&self) -> &[u8] {
537 self.storage.as_ref()
538 }
539
540 #[inline]
541 fn advance(&mut self, cnt: usize) {
542 assert!(cnt <= self.storage.len(), "cannot advance past `remaining`");
543 unsafe {
544 self.storage.set_start(cnt);
545 }
546 }
547}
548
549impl bytes::buf::Buf for Bytes {
550 #[inline]
551 fn remaining(&self) -> usize {
552 self.len()
553 }
554
555 #[inline]
556 fn chunk(&self) -> &[u8] {
557 self.storage.as_ref()
558 }
559
560 #[inline]
561 fn advance(&mut self, cnt: usize) {
562 assert!(cnt <= self.storage.len(), "cannot advance past `remaining`");
563 unsafe {
564 self.storage.set_start(cnt);
565 }
566 }
567}
568
569impl Clone for Bytes {
570 fn clone(&self) -> Bytes {
571 Bytes {
572 storage: self.storage.clone(),
573 }
574 }
575}
576
577impl AsRef<[u8]> for Bytes {
578 #[inline]
579 fn as_ref(&self) -> &[u8] {
580 self.storage.as_ref()
581 }
582}
583
584impl ops::Deref for Bytes {
585 type Target = [u8];
586
587 #[inline]
588 fn deref(&self) -> &[u8] {
589 self.storage.as_ref()
590 }
591}
592
593impl From<&Bytes> for Bytes {
594 fn from(src: &Bytes) -> Bytes {
595 src.clone()
596 }
597}
598
599impl From<BytesMut> for Bytes {
600 fn from(src: BytesMut) -> Bytes {
601 src.freeze()
602 }
603}
604
605impl From<Vec<u8>> for Bytes {
606 /// Convert a `Vec` into a `Bytes`
607 fn from(src: Vec<u8>) -> Bytes {
608 if src.len() <= INLINE_CAP {
609 Bytes {
610 storage: Storage::from_slice(&src),
611 }
612 } else {
613 Bytes {
614 storage: Storage::from_vec(src),
615 }
616 }
617 }
618}
619
620impl From<String> for Bytes {
621 fn from(src: String) -> Bytes {
622 if src.len() <= INLINE_CAP {
623 Bytes {
624 storage: Storage::from_slice(src.as_bytes()),
625 }
626 } else {
627 Bytes {
628 storage: Storage::from_vec(src.into_bytes()),
629 }
630 }
631 }
632}
633
634impl From<&'static [u8]> for Bytes {
635 fn from(src: &'static [u8]) -> Bytes {
636 Bytes::from_static(src)
637 }
638}
639
640impl From<&'static str> for Bytes {
641 fn from(src: &'static str) -> Bytes {
642 Bytes::from_static(src.as_bytes())
643 }
644}
645
646impl<'a, const N: usize> From<&'a [u8; N]> for Bytes {
647 fn from(src: &'a [u8; N]) -> Bytes {
648 Bytes::copy_from_slice(src)
649 }
650}
651
652impl FromIterator<u8> for Bytes {
653 fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self {
654 BytesMut::from_iter(into_iter).freeze()
655 }
656}
657
658impl<'a> FromIterator<&'a u8> for Bytes {
659 fn from_iter<T: IntoIterator<Item = &'a u8>>(into_iter: T) -> Self {
660 BytesMut::from_iter(into_iter).freeze()
661 }
662}
663
664impl Eq for Bytes {}
665
666impl PartialEq for Bytes {
667 fn eq(&self, other: &Bytes) -> bool {
668 self.storage.as_ref() == other.storage.as_ref()
669 }
670}
671
672impl PartialOrd for Bytes {
673 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
674 Some(self.cmp(other))
675 }
676}
677
678impl Ord for Bytes {
679 fn cmp(&self, other: &Bytes) -> cmp::Ordering {
680 self.storage.as_ref().cmp(other.storage.as_ref())
681 }
682}
683
684impl Default for Bytes {
685 #[inline]
686 fn default() -> Bytes {
687 Bytes::new()
688 }
689}
690
691impl fmt::Debug for Bytes {
692 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
693 fmt::Debug::fmt(&debug::BsDebug(self.storage.as_ref()), fmt)
694 }
695}
696
697impl hash::Hash for Bytes {
698 fn hash<H>(&self, state: &mut H)
699 where
700 H: hash::Hasher,
701 {
702 let s: &[u8] = self.as_ref();
703 s.hash(state);
704 }
705}
706
707impl borrow::Borrow<[u8]> for Bytes {
708 fn borrow(&self) -> &[u8] {
709 self.as_ref()
710 }
711}
712
713impl IntoIterator for Bytes {
714 type Item = u8;
715 type IntoIter = IntoIter<Bytes>;
716
717 fn into_iter(self) -> Self::IntoIter {
718 IntoIter::new(self)
719 }
720}
721
722impl<'a> IntoIterator for &'a Bytes {
723 type Item = &'a u8;
724 type IntoIter = std::slice::Iter<'a, u8>;
725
726 fn into_iter(self) -> Self::IntoIter {
727 self.as_ref().iter()
728 }
729}
730
731/*
732 *
733 * ===== PartialEq / PartialOrd =====
734 *
735 */
736
737impl PartialEq<[u8]> for Bytes {
738 fn eq(&self, other: &[u8]) -> bool {
739 self.storage.as_ref() == other
740 }
741}
742
743impl<const N: usize> PartialEq<[u8; N]> for Bytes {
744 fn eq(&self, other: &[u8; N]) -> bool {
745 self.storage.as_ref() == other.as_ref()
746 }
747}
748
749impl PartialOrd<[u8]> for Bytes {
750 fn partial_cmp(&self, other: &[u8]) -> Option<cmp::Ordering> {
751 self.storage.as_ref().partial_cmp(other)
752 }
753}
754
755impl<const N: usize> PartialOrd<[u8; N]> for Bytes {
756 fn partial_cmp(&self, other: &[u8; N]) -> Option<cmp::Ordering> {
757 self.storage.as_ref().partial_cmp(other.as_ref())
758 }
759}
760
761impl PartialEq<Bytes> for [u8] {
762 fn eq(&self, other: &Bytes) -> bool {
763 *other == *self
764 }
765}
766
767impl<const N: usize> PartialEq<Bytes> for [u8; N] {
768 fn eq(&self, other: &Bytes) -> bool {
769 *other == *self
770 }
771}
772
773impl<const N: usize> PartialEq<Bytes> for &[u8; N] {
774 fn eq(&self, other: &Bytes) -> bool {
775 *other == *self
776 }
777}
778
779impl PartialOrd<Bytes> for [u8] {
780 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
781 other.partial_cmp(self)
782 }
783}
784
785impl<const N: usize> PartialOrd<Bytes> for [u8; N] {
786 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
787 other.partial_cmp(self)
788 }
789}
790
791impl PartialEq<str> for Bytes {
792 fn eq(&self, other: &str) -> bool {
793 self.storage.as_ref() == other.as_bytes()
794 }
795}
796
797impl PartialOrd<str> for Bytes {
798 fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
799 self.storage.as_ref().partial_cmp(other.as_bytes())
800 }
801}
802
803impl PartialEq<Bytes> for str {
804 fn eq(&self, other: &Bytes) -> bool {
805 *other == *self
806 }
807}
808
809impl PartialOrd<Bytes> for str {
810 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
811 other.partial_cmp(self)
812 }
813}
814
815impl PartialEq<Vec<u8>> for Bytes {
816 fn eq(&self, other: &Vec<u8>) -> bool {
817 *self == other[..]
818 }
819}
820
821impl PartialOrd<Vec<u8>> for Bytes {
822 fn partial_cmp(&self, other: &Vec<u8>) -> Option<cmp::Ordering> {
823 self.storage.as_ref().partial_cmp(&other[..])
824 }
825}
826
827impl PartialEq<Bytes> for Vec<u8> {
828 fn eq(&self, other: &Bytes) -> bool {
829 *other == *self
830 }
831}
832
833impl PartialOrd<Bytes> for Vec<u8> {
834 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
835 other.partial_cmp(self)
836 }
837}
838
839impl PartialEq<String> for Bytes {
840 fn eq(&self, other: &String) -> bool {
841 *self == other[..]
842 }
843}
844
845impl PartialOrd<String> for Bytes {
846 fn partial_cmp(&self, other: &String) -> Option<cmp::Ordering> {
847 self.storage.as_ref().partial_cmp(other.as_bytes())
848 }
849}
850
851impl PartialEq<Bytes> for String {
852 fn eq(&self, other: &Bytes) -> bool {
853 *other == *self
854 }
855}
856
857impl PartialOrd<Bytes> for String {
858 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
859 other.partial_cmp(self)
860 }
861}
862
863impl PartialEq<Bytes> for &[u8] {
864 fn eq(&self, other: &Bytes) -> bool {
865 *other == *self
866 }
867}
868
869impl PartialOrd<Bytes> for &[u8] {
870 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
871 other.partial_cmp(self)
872 }
873}
874
875impl PartialEq<Bytes> for &str {
876 fn eq(&self, other: &Bytes) -> bool {
877 *other == *self
878 }
879}
880
881impl PartialOrd<Bytes> for &str {
882 fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
883 other.partial_cmp(self)
884 }
885}
886
887impl<'a, T: ?Sized> PartialEq<&'a T> for Bytes
888where
889 Bytes: PartialEq<T>,
890{
891 fn eq(&self, other: &&'a T) -> bool {
892 *self == **other
893 }
894}
895
896impl<'a, T: ?Sized> PartialOrd<&'a T> for Bytes
897where
898 Bytes: PartialOrd<T>,
899{
900 fn partial_cmp(&self, other: &&'a T) -> Option<cmp::Ordering> {
901 self.partial_cmp(&**other)
902 }
903}
904
905impl PartialEq<BytesMut> for Bytes {
906 fn eq(&self, other: &BytesMut) -> bool {
907 other[..] == self[..]
908 }
909}
910
911#[cfg(test)]
912mod tests {
913 use std::collections::HashMap;
914
915 use super::*;
916 use crate::BufMut;
917
918 const LONG: &[u8] = b"mary had a little lamb, little lamb, little lamb, little lamb, little lamb, little lamb \
919 mary had a little lamb, little lamb, little lamb, little lamb, little lamb, little lamb \
920 mary had a little lamb, little lamb, little lamb, little lamb, little lamb, little lamb";
921
922 #[test]
923 #[allow(
924 clippy::len_zero,
925 clippy::nonminimal_bool,
926 clippy::unnecessary_fallible_conversions
927 )]
928 fn bytes() {
929 let mut b = Bytes::from(LONG.to_vec());
930 b.clear();
931 assert!(b.is_inline());
932 assert!(b.is_empty());
933 assert!(b.len() == 0);
934
935 let b = Bytes::from(&Bytes::from(LONG));
936 assert_eq!(b, LONG);
937
938 let b = Bytes::from(BytesMut::from(LONG));
939 assert_eq!(b, LONG);
940
941 let mut b: Bytes = BytesMut::try_from(b).unwrap().freeze();
942 assert_eq!(b, LONG);
943 assert!(!(b > b));
944 assert_eq!(<Bytes as Buf>::remaining(&b), LONG.len());
945 assert_eq!(<Bytes as Buf>::chunk(&b), LONG);
946 <Bytes as Buf>::advance(&mut b, 10);
947 assert_eq!(Buf::chunk(&b), &LONG[10..]);
948
949 let mut h: HashMap<Bytes, usize> = HashMap::default();
950 h.insert(b.clone(), 1);
951 assert_eq!(h.get(&b), Some(&1));
952
953 let mut b = BytesMut::try_from(LONG).unwrap();
954 assert_eq!(b, LONG);
955 assert_eq!(<BytesMut as Buf>::remaining(&b), LONG.len());
956 assert_eq!(<BytesMut as BufMut>::remaining_mut(&b), 1);
957 assert_eq!(<BytesMut as Buf>::chunk(&b), LONG);
958 <BytesMut as Buf>::advance(&mut b, 10);
959 assert_eq!(<BytesMut as Buf>::chunk(&b), &LONG[10..]);
960
961 let mut b = BytesMut::with_capacity(12);
962 <BytesMut as BufMut>::put_i8(&mut b, 1);
963 assert_eq!(b, b"\x01".as_ref());
964 <BytesMut as BufMut>::put_u8(&mut b, 2);
965 assert_eq!(b, b"\x01\x02".as_ref());
966 <BytesMut as BufMut>::put_slice(&mut b, b"12345");
967 assert_eq!(b, b"\x01\x0212345".as_ref());
968 <BytesMut as BufMut>::chunk_mut(&mut b).write_byte(0, b'1');
969 unsafe { <BytesMut as BufMut>::advance_mut(&mut b, 1) };
970 assert_eq!(b, b"\x01\x02123451".as_ref());
971 }
972}