Skip to main content

ntex_bytes/
bytes.rs

1use std::{cmp, hash, mem, ops};
2
3use crate::{Buf, BytesMut, 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 points to a section of the
58/// memory region, and `Bytes` handles may or may not have overlapping views
59/// into the memory.
60///
61/// ```text
62///
63///    Arc ptrs                   +---------+
64///    ________________________ / | Bytes 2 |
65///   /                           +---------+
66///  /          +-----------+     |         |
67/// |_________/ |  Bytes 1  |     |         |
68/// |           +-----------+     |         |
69/// |           |           | ___/ data     | tail
70/// |      data |      tail |/              |
71/// v           v           v               v
72/// +-----+---------------------------------+-----+
73/// | MD  |     |           |               |     |
74/// +-----+---------------------------------+-----+
75/// ```
76///
77/// # Mutating
78///
79/// While `Bytes` handles may represent overlapping views of the underlying
80/// memory slice and therefore cannot be mutated, `BytesMut` handles are
81/// guaranteed to be the only handle able to view that slice of memory. As such,
82/// `BytesMut` handles may mutate the underlying memory. Note that holding a
83/// unique view of a region of memory does not mean there are no other `Bytes`
84/// handles with disjoint views of the same underlying allocation.
85///
86/// # Inline bytes
87///
88/// As an optimization, when the slice referenced by a `Bytes` handle is small
89/// enough [^1], the data may be stored inline. In this case, a clone is no longer
90/// “shallow”, and the data will be copied. `BytesMut` does not support data
91/// inlining and always allocates, but during conversion to `Bytes`, data from
92/// `BytesMut` may be inlined.
93///
94/// [^1]: Small enough: 23 bytes on 64 bit systems, 11 on 32 bit systems.
95///
96pub struct Bytes {
97    pub(crate) storage: Storage,
98}
99
100/*
101 *
102 * ===== Bytes =====
103 *
104 */
105
106impl Bytes {
107    /// Creates a new empty `Bytes`.
108    ///
109    /// This will not allocate and the returned `Bytes` handle will be empty.
110    ///
111    /// # Examples
112    ///
113    /// ```
114    /// use ntex_bytes::Bytes;
115    ///
116    /// let b = Bytes::new();
117    /// assert_eq!(&b[..], b"");
118    /// ```
119    #[inline]
120    pub const fn new() -> Bytes {
121        Bytes {
122            storage: Storage::empty(),
123        }
124    }
125
126    /// Creates a new `Bytes` from a static slice.
127    ///
128    /// The returned `Bytes` will point directly to the static slice. There is
129    /// no allocating or copying.
130    ///
131    /// # Examples
132    ///
133    /// ```
134    /// use ntex_bytes::Bytes;
135    ///
136    /// let b = Bytes::from_static(b"hello");
137    /// assert_eq!(&b[..], b"hello");
138    /// ```
139    #[inline]
140    #[must_use]
141    pub const fn from_static(bytes: &'static [u8]) -> Bytes {
142        Bytes {
143            storage: Storage::from_static(bytes),
144        }
145    }
146
147    /// Returns the number of bytes contained in this `Bytes`.
148    ///
149    /// # Examples
150    ///
151    /// ```
152    /// use ntex_bytes::Bytes;
153    ///
154    /// let b = Bytes::from(&b"hello"[..]);
155    /// assert_eq!(b.len(), 5);
156    /// ```
157    #[inline]
158    pub fn len(&self) -> usize {
159        self.storage.len()
160    }
161
162    /// Returns true if the `Bytes` has a length of 0.
163    ///
164    /// # Examples
165    ///
166    /// ```
167    /// use ntex_bytes::Bytes;
168    ///
169    /// let b = Bytes::new();
170    /// assert!(b.is_empty());
171    /// ```
172    #[inline]
173    pub fn is_empty(&self) -> bool {
174        self.storage.is_empty()
175    }
176
177    /// Returns `true` if the bytes are stored inline.
178    ///
179    /// # Examples
180    /// ```
181    /// use ntex_bytes::{Bytes, BytesMut};
182    ///
183    /// assert!(Bytes::from(BytesMut::from(&[0, 0, 0, 0][..])).is_inline());
184    /// assert!(Bytes::from(Vec::with_capacity(4)).is_inline());
185    /// assert!(!Bytes::from(&[0; 1024][..]).is_inline());
186    /// ```
187    pub fn is_inline(&self) -> bool {
188        self.storage.is_inline()
189    }
190
191    /// Creates a `Bytes` value by copying a byte slice.
192    ///
193    /// Data from the slice could be inlined.
194    #[must_use]
195    pub fn copy_from_slice(data: &[u8]) -> Self {
196        Bytes {
197            storage: Storage::from_slice(data),
198        }
199    }
200
201    /// Returns a slice of self for the provided range.
202    ///
203    /// This will increment the reference count for the underlying memory and
204    /// return a new `Bytes` handle set to the slice. A slice that fits inline
205    /// is copied instead.
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    /// Returns `None` unless `begin <= end` and `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.checked_add(1)?,
244            Bound::Unbounded => 0,
245        };
246
247        let end = match range.end_bound() {
248            Bound::Included(&n) => n.checked_add(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 `subset` 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 `subset` slice is not contained within the `Bytes` buffer")
300    }
301
302    /// Returns a slice of self that is equivalent to the given `subset`.
303    ///
304    /// Returns `None` if `subset` is not contained within the `Bytes` buffer.
305    #[must_use]
306    pub fn slice_ref_checked(&self, subset: &[u8]) -> Option<Bytes> {
307        let bytes_p = self.as_ptr() as usize;
308        let bytes_len = self.len();
309
310        let sub_p = subset.as_ptr() as usize;
311        let sub_len = subset.len();
312
313        if sub_p >= bytes_p && sub_p + sub_len <= bytes_p + bytes_len {
314            let sub_offset = sub_p - bytes_p;
315            Some(self.slice(sub_offset..(sub_offset + sub_len)))
316        } else {
317            None
318        }
319    }
320
321    /// Splits the bytes into two at the given index.
322    ///
323    /// Afterwards `self` contains elements `[0, at)`, and the returned `Bytes`
324    /// contains elements `[at, len)`.
325    ///
326    /// This is an `O(1)` operation that just increases the reference count and
327    /// sets a few indices.
328    ///
329    /// # Examples
330    ///
331    /// ```
332    /// use ntex_bytes::Bytes;
333    ///
334    /// let mut a = Bytes::from(&b"hello world"[..]);
335    /// let b = a.split_off(5);
336    ///
337    /// assert_eq!(a, b"hello");
338    /// assert_eq!(b, b" world");
339    /// ```
340    ///
341    /// # Panics
342    ///
343    /// Panics if `at > self.len()`.
344    #[must_use]
345    #[inline]
346    pub fn split_off(&mut self, at: usize) -> Bytes {
347        self.split_off_checked(at)
348            .expect("at value must be <= self.len()`")
349    }
350
351    /// Splits the bytes into two at the given index.
352    ///
353    /// Returns `None` if `at > self.len()`.
354    #[must_use]
355    #[inline]
356    pub fn split_off_checked(&mut self, at: usize) -> Option<Bytes> {
357        if at <= self.len() {
358            if at == self.len() {
359                Some(Bytes::new())
360            } else if at == 0 {
361                Some(mem::take(self))
362            } else {
363                Some(Bytes {
364                    storage: self.storage.split_off(at, true),
365                })
366            }
367        } else {
368            None
369        }
370    }
371
372    /// Splits the bytes into two at the given index.
373    ///
374    /// Afterwards `self` contains elements `[at, len)`, and the returned
375    /// `Bytes` contains elements `[0, at)`.
376    ///
377    /// This is an `O(1)` operation that just increases the reference count and
378    /// sets a few indices.
379    ///
380    /// # Examples
381    ///
382    /// ```
383    /// use ntex_bytes::Bytes;
384    ///
385    /// let mut a = Bytes::from(&b"hello world"[..]);
386    /// let b = a.split_to(5);
387    ///
388    /// assert_eq!(a, b" world");
389    /// assert_eq!(b, b"hello");
390    /// ```
391    ///
392    /// # Panics
393    ///
394    /// Panics if `at > len`.
395    #[must_use]
396    #[inline]
397    pub fn split_to(&mut self, at: usize) -> Bytes {
398        self.split_to_checked(at)
399            .expect("at value must be <= self.len()`")
400    }
401
402    /// Splits the bytes into two at the given index.
403    ///
404    /// Returns `None` if `at > len`.
405    #[must_use]
406    #[inline]
407    pub fn split_to_checked(&mut self, at: usize) -> Option<Bytes> {
408        if at <= self.len() {
409            if at == self.len() {
410                Some(mem::take(self))
411            } else if at == 0 {
412                Some(Bytes::new())
413            } else {
414                Some(Bytes {
415                    storage: self.storage.split_to(at),
416                })
417            }
418        } else {
419            None
420        }
421    }
422
423    /// Advance the internal cursor.
424    ///
425    /// Afterwards `self` contains elements `[cnt, len)`.
426    /// This is an `O(1)` operation.
427    ///
428    /// # Examples
429    ///
430    /// ```
431    /// use ntex_bytes::Bytes;
432    ///
433    /// let mut a = Bytes::copy_from_slice(&b"hello world"[..]);
434    /// a.advance_to(5);
435    ///
436    /// assert_eq!(&a[..], b" world");
437    /// ```
438    ///
439    /// # Panics
440    ///
441    /// Panics if `cnt > len`.
442    #[inline]
443    pub fn advance_to(&mut self, cnt: usize) {
444        unsafe {
445            self.storage.set_start(cnt);
446        }
447    }
448
449    /// Shortens the buffer, keeping the first `len` bytes and dropping the
450    /// rest.
451    ///
452    /// If `len` is greater than the buffer's current length, this has no
453    /// effect. The data may be inlined if it fits.
454    ///
455    /// The [`split_off`] method can emulate `truncate`, but this causes the
456    /// excess bytes to be returned instead of dropped.
457    ///
458    /// # Examples
459    ///
460    /// ```
461    /// use ntex_bytes::Bytes;
462    ///
463    /// let mut buf = Bytes::from(&b"hello world"[..]);
464    /// buf.truncate(5);
465    /// assert_eq!(buf, b"hello"[..]);
466    /// ```
467    ///
468    /// [`split_off`]: #method.split_off
469    #[inline]
470    pub fn truncate(&mut self, len: usize) {
471        self.storage.truncate(len);
472    }
473
474    /// Compacts the underlying storage to this value's current byte range.
475    ///
476    /// This can reduce retained capacity when this value is a small view into a
477    /// larger allocation, anywhere within the allocation. The data is copied if
478    /// the allocation is larger than the view by at least 64 bytes, views up to
479    /// the inline capacity are always inlined. The visible bytes are unchanged.
480    ///
481    /// # Examples
482    ///
483    /// ```
484    /// use ntex_bytes::Bytes;
485    ///
486    /// let mut buf = Bytes::from(&b"hello world"[..]);
487    /// buf.trimdown();
488    /// assert_eq!(buf, b"hello world"[..]);
489    /// ```
490    #[inline]
491    pub fn trimdown(&mut self) {
492        self.storage.trimdown();
493    }
494
495    /// Clears the buffer, removing all data.
496    ///
497    /// # Examples
498    ///
499    /// ```
500    /// use ntex_bytes::Bytes;
501    ///
502    /// let mut buf = Bytes::from(&b"hello world"[..]);
503    /// buf.clear();
504    /// assert!(buf.is_empty());
505    /// ```
506    #[inline]
507    pub fn clear(&mut self) {
508        self.storage = Storage::empty();
509    }
510
511    /// Returns an iterator over the bytes contained by the buffer.
512    ///
513    /// # Examples
514    ///
515    /// ```
516    /// use ntex_bytes::{Buf, Bytes};
517    ///
518    /// let buf = Bytes::from(&b"abc"[..]);
519    /// let mut iter = buf.iter();
520    ///
521    /// assert_eq!(iter.next().map(|b| *b), Some(b'a'));
522    /// assert_eq!(iter.next().map(|b| *b), Some(b'b'));
523    /// assert_eq!(iter.next().map(|b| *b), Some(b'c'));
524    /// assert_eq!(iter.next(), None);
525    /// ```
526    pub fn iter(&'_ self) -> std::slice::Iter<'_, u8> {
527        self.chunk().iter()
528    }
529
530    #[inline]
531    #[doc(hidden)]
532    pub fn info(&self) -> crate::info::Info {
533        self.storage.info()
534    }
535}
536
537impl_buf!(Bytes {
538    #[inline]
539    fn get_u8(&mut self) -> u8 {
540        self.storage.get_u8()
541    }
542});
543
544impl_slice_traits!(Bytes);
545
546impl Clone for Bytes {
547    #[inline]
548    fn clone(&self) -> Bytes {
549        Bytes {
550            storage: self.storage.clone(),
551        }
552    }
553}
554
555impl From<&Bytes> for Bytes {
556    fn from(src: &Bytes) -> Bytes {
557        src.clone()
558    }
559}
560
561impl From<crate::ByteString> for Bytes {
562    fn from(src: crate::ByteString) -> Bytes {
563        src.into_bytes()
564    }
565}
566
567impl From<&crate::ByteString> for Bytes {
568    fn from(src: &crate::ByteString) -> Bytes {
569        src.clone().into_bytes()
570    }
571}
572
573impl From<Vec<u8>> for Bytes {
574    /// Convert a `Vec` into a `Bytes`
575    fn from(src: Vec<u8>) -> Bytes {
576        Bytes {
577            storage: Storage::from_slice(&src),
578        }
579    }
580}
581
582impl From<String> for Bytes {
583    fn from(src: String) -> Bytes {
584        Bytes {
585            storage: Storage::from_slice(src.as_bytes()),
586        }
587    }
588}
589
590impl From<&'static [u8]> for Bytes {
591    fn from(src: &'static [u8]) -> Bytes {
592        Bytes::from_static(src)
593    }
594}
595
596impl From<&'static str> for Bytes {
597    fn from(src: &'static str) -> Bytes {
598        Bytes::from_static(src.as_bytes())
599    }
600}
601
602impl<'a, const N: usize> From<&'a [u8; N]> for Bytes {
603    fn from(src: &'a [u8; N]) -> Bytes {
604        Bytes::copy_from_slice(src)
605    }
606}
607
608impl FromIterator<u8> for Bytes {
609    fn from_iter<T: IntoIterator<Item = u8>>(into_iter: T) -> Self {
610        BytesMut::from_iter(into_iter).freeze()
611    }
612}
613
614impl<'a> FromIterator<&'a u8> for Bytes {
615    fn from_iter<T: IntoIterator<Item = &'a u8>>(into_iter: T) -> Self {
616        BytesMut::from_iter(into_iter).freeze()
617    }
618}
619
620impl Eq for Bytes {}
621
622impl PartialEq for Bytes {
623    fn eq(&self, other: &Bytes) -> bool {
624        self.storage.as_ref() == other.storage.as_ref()
625    }
626}
627
628impl PartialOrd for Bytes {
629    fn partial_cmp(&self, other: &Bytes) -> Option<cmp::Ordering> {
630        Some(self.cmp(other))
631    }
632}
633
634impl Ord for Bytes {
635    fn cmp(&self, other: &Bytes) -> cmp::Ordering {
636        self.storage.as_ref().cmp(other.storage.as_ref())
637    }
638}
639
640impl_read!(Bytes);
641
642impl hash::Hash for Bytes {
643    fn hash<H>(&self, state: &mut H)
644    where
645        H: hash::Hasher,
646    {
647        let s: &[u8] = self.as_ref();
648        s.hash(state);
649    }
650}
651
652impl_partial_eq!(Bytes);
653impl_partial_ord!(Bytes);
654
655#[cfg(test)]
656#[allow(unused_must_use)]
657mod tests {
658    use std::collections::HashMap;
659
660    use super::*;
661    use crate::BufMut;
662
663    const LONG: &[u8] = b"mary had a1 little la2mb, little lamb, little lamb, little lamb, little lamb, little lamb \
664        mary had a little lamb, little lamb, little lamb, little lamb, little lamb, little lamb \
665        mary had a little lamb, little lamb, little lamb, little lamb, little lamb, little lamb \0";
666
667    #[test]
668    #[allow(clippy::op_ref, clippy::cmp_owned)]
669    fn partial_ord_reverse() {
670        let b = Bytes::from_static(b"b");
671        assert!(b"a"[..] < b);
672        assert!(*b"a" < b);
673        assert!(*"a" < b);
674        assert!(b"a".to_vec() < b);
675        assert!(String::from("a") < b);
676        assert!(&b"a"[..] < b);
677        assert!("a" < b);
678        assert!(b"c"[..] > b);
679        assert!("c" > b);
680        assert_eq!(b"b"[..].partial_cmp(&b), Some(cmp::Ordering::Equal));
681    }
682
683    #[test]
684    fn slice_checked_max_bounds() {
685        use std::ops::Bound;
686
687        let b = Bytes::from(LONG.to_vec());
688        assert!(b.slice_checked(..=usize::MAX).is_none());
689        assert!(
690            b.slice_checked((Bound::Excluded(usize::MAX), Bound::Unbounded))
691                .is_none()
692        );
693    }
694
695    #[test]
696    #[allow(
697        clippy::op_ref,
698        clippy::len_zero,
699        clippy::nonminimal_bool,
700        clippy::unnecessary_fallible_conversions
701    )]
702    fn bytes() {
703        let mut b = Bytes::from(LONG.to_vec());
704        b.advance_to(10);
705        assert_eq!(&b, &LONG[10..]);
706        b.advance_to(10);
707        assert_eq!(&b[..], &LONG[20..]);
708        assert_eq!(&b, &LONG[20..]);
709        b.clear();
710        assert!(b.is_inline());
711        assert!(b.is_empty());
712        assert_eq!(b.len(), 0);
713
714        let mut b = Bytes::from(LONG);
715        b.advance_to(10);
716        assert_eq!(&b, &LONG[10..]);
717        b.advance_to(10);
718        assert_eq!(&b[..], &LONG[20..]);
719        assert_eq!(&b, &LONG[20..]);
720        b.clear();
721        assert!(b.is_empty());
722        assert_eq!(b.len(), 0);
723
724        let mut b = Bytes::from(LONG);
725        b.split_off(10);
726        assert_eq!(&b, &LONG[..10]);
727        b.advance_to(5);
728        assert_eq!(&b, &LONG[5..10]);
729
730        let mut b = Bytes::copy_from_slice(&LONG[..15]);
731        assert!(b.is_inline());
732        b.split_off(10);
733        assert_eq!(&b, &LONG[..10]);
734        b.advance_to(1);
735        assert_eq!(&b, &LONG[1..10]);
736
737        let mut b = Bytes::from(b"123");
738        assert!(&b"12"[..] < &b);
739        assert_eq!("123", &b);
740        assert!("12" < &b);
741        assert!("12" < b);
742        assert_eq!(b.get_u8(), b'1');
743        assert_eq!("23", &b);
744
745        let mut b = Bytes::from(&Bytes::from(LONG));
746        assert_eq!(b, LONG);
747        assert_eq!(b.get_u8(), LONG[0]);
748        assert_eq!(b.get_u8(), LONG[1]);
749        assert_eq!(b.len(), LONG.len() - 2);
750
751        let b = Bytes::from(BytesMut::from(LONG));
752        assert_eq!(b, LONG);
753
754        let mut b: Bytes = BytesMut::try_from(b).unwrap().freeze();
755        assert_eq!(b, LONG);
756        assert!(!(b > b));
757        assert_eq!(<Bytes as Buf>::remaining(&b), LONG.len());
758        assert_eq!(<Bytes as Buf>::chunk(&b), LONG);
759        <Bytes as Buf>::advance(&mut b, 10);
760        assert_eq!(Buf::chunk(&b), &LONG[10..]);
761        <Bytes as Buf>::advance(&mut b, 10);
762        assert_eq!(Buf::chunk(&b), &LONG[20..]);
763
764        let mut h: HashMap<Bytes, usize> = HashMap::default();
765        h.insert(b.clone(), 1);
766        assert_eq!(h.get(&b), Some(&1));
767
768        let mut b = BytesMut::try_from(LONG).unwrap();
769        assert_eq!(b, LONG);
770        assert_eq!(<BytesMut as Buf>::remaining(&b), LONG.len());
771        assert_eq!(<BytesMut as BufMut>::remaining_mut(&b), 0);
772        assert_eq!(<BytesMut as Buf>::chunk(&b), LONG);
773        <BytesMut as Buf>::advance(&mut b, 10);
774        assert_eq!(<BytesMut as Buf>::chunk(&b), &LONG[10..]);
775
776        let mut b = BytesMut::with_capacity(12);
777        <BytesMut as BufMut>::put_i8(&mut b, 1);
778        assert_eq!(b, b"\x01".as_ref());
779        <BytesMut as BufMut>::put_u8(&mut b, 2);
780        assert_eq!(b, b"\x01\x02".as_ref());
781        <BytesMut as BufMut>::put_slice(&mut b, b"12345");
782        assert_eq!(b, b"\x01\x0212345".as_ref());
783        <BytesMut as BufMut>::chunk_mut(&mut b).write_byte(0, b'1');
784        unsafe { <BytesMut as BufMut>::advance_mut(&mut b, 1) };
785        assert_eq!(b, b"\x01\x02123451".as_ref());
786
787        let mut iter = Bytes::from(LONG.to_vec()).into_iter();
788        assert_eq!(iter.next(), Some(LONG[0]));
789        assert_eq!(iter.next(), Some(LONG[1]));
790        assert_eq!(iter.next(), Some(LONG[2]));
791        assert_eq!(iter.next(), Some(LONG[3]));
792        assert_eq!(iter.get_ref(), &LONG[4..]);
793        assert_eq!(iter.get_mut(), &LONG[4..]);
794        let b = iter.into_inner();
795        assert_eq!(b, &LONG[4..]);
796
797        let mut b = Bytes::copy_from_slice(b"123");
798        assert!(b.is_inline());
799        assert_eq!(b.storage.capacity(), 23);
800        b.truncate(2);
801        assert_eq!(b, *b"12");
802        assert_eq!(bytes::buf::Buf::get_u8(&mut b), 49);
803        assert_eq!(b.len(), 1);
804    }
805
806    #[test]
807    fn bytes_read() {
808        use std::io::Read;
809
810        let mut b = Bytes::copy_from_slice(b"123");
811
812        let mut buf = [0; 10];
813        assert_eq!(b.read(&mut buf).unwrap(), 3);
814        assert_eq!(b.len(), 0);
815        assert_eq!(buf, [49, 50, 51, 0, 0, 0, 0, 0, 0, 0]);
816    }
817
818    #[test]
819    fn from_byte_string() {
820        let s = crate::ByteString::from_static("string");
821        assert_eq!(Bytes::from(&s), "string");
822        assert_eq!(Bytes::from(s), "string");
823    }
824}