diff --git a/src/buf.rs b/src/buf.rs index 495478ef0acd99851ff775ea4fc9e33b19b1eb14..1016e0b9fb7a5f7ffb5b9825184aa057489d4555 100644 --- a/src/buf.rs +++ b/src/buf.rs @@ -4,9 +4,10 @@ use std::{cmp, io, ptr, usize}; /// Read bytes from a buffer. /// -/// A buffer stores bytes in memory such that read access is infallible. The -/// underlying storage may or may not be in contiguous memory. A `Buf` value is -/// a cursor into the buffer. Reading from `Buf` advances the cursor position. +/// A buffer stores bytes in memory such that read operations are infallible. +/// The underlying storage may or may not be in contiguous memory. A `Buf` value +/// is a cursor into the buffer. Reading from `Buf` advances the cursor +/// position. /// /// The simplest `Buf` is a `Cursor` wrapping a `[u8]`. /// @@ -35,10 +36,10 @@ pub trait Buf { /// # Examples /// /// ``` - /// use bytes::{Bytes, Buf, IntoBuf}; + /// use bytes::Buf; + /// use std::io::Cursor; /// - /// let bytes = Bytes::from("hello world"); - /// let mut buf = bytes.into_buf(); + /// let mut buf = Cursor::new(b"hello world"); /// /// assert_eq!(buf.remaining(), 11); /// @@ -57,10 +58,10 @@ pub trait Buf { /// # Examples /// /// ``` - /// use bytes::{Bytes, Buf, IntoBuf}; + /// use bytes::Buf; + /// use std::io::Cursor; /// - /// let bytes = Bytes::from("hello world"); - /// let mut buf = bytes.into_buf(); + /// let mut buf = Cursor::new(b"hello world"); /// /// assert_eq!(buf.bytes(), b"hello world"); /// @@ -78,10 +79,10 @@ pub trait Buf { /// # Examples /// /// ``` - /// use bytes::{Bytes, Buf, IntoBuf}; + /// use bytes::Buf; + /// use std::io::Cursor; /// - /// let bytes = Bytes::from("hello world"); - /// let mut buf = bytes.into_buf(); + /// let mut buf = Cursor::new(b"hello world"); /// /// assert_eq!(buf.bytes(), b"hello world"); /// @@ -97,15 +98,15 @@ pub trait Buf { /// Returns true if there are any more bytes to consume /// - /// This is equivalent to `self.remaining() == 0`. + /// This is equivalent to `self.remaining() != 0`. /// /// # Examples /// /// ``` - /// use bytes::{Bytes, Buf, IntoBuf}; + /// use bytes::Buf; + /// use std::io::Cursor; /// - /// let bytes = Bytes::from("a"); - /// let mut buf = bytes.into_buf(); + /// let mut buf = Cursor::new(b"a"); /// /// assert!(buf.has_remaining()); /// @@ -391,7 +392,7 @@ pub trait Buf { T::read_int(&buf[..nbytes], nbytes) } - /// Gets a IEEE754 single-precision (4 bytes) floating point number from + /// Gets an IEEE754 single-precision (4 bytes) floating point number from /// `self` in the specified byte order. /// /// The current position is advanced by 4. @@ -415,7 +416,7 @@ pub trait Buf { T::read_f32(&buf) } - /// Gets a IEEE754 doublee-precision (8 bytes) floating point number from + /// Gets an IEEE754 double-precision (8 bytes) floating point number from /// `self` in the specified byte order. /// /// The current position is advanced by 8. @@ -470,7 +471,7 @@ pub trait Buf { } } - /// Creates a "by reference" adaptor for this instance of Buf + /// Creates a "by reference" adaptor for this instance of `Buf`. /// /// The returned adaptor also implements `Buf` and will simply borrow `self`. /// @@ -524,38 +525,167 @@ pub trait Buf { } /// A trait for values that provide sequential write access to bytes. +/// +/// Write bytes to a buffer +/// +/// A buffer stores bytes in memory such that write operations are infallible. +/// The underlying storage may or may not be in contiguous memory. A `BufMut` +/// value is a cursor into the buffer. Writing to `BufMut` advances the cursor +/// position. +/// +/// The simplest `BufMut` is a `Vec<u8>`. +/// +/// ``` +/// use bytes::BufMut; +/// +/// let mut buf = vec![]; +/// +/// buf.put("hello world"); +/// +/// assert_eq!(buf, b"hello world"); +/// ``` pub trait BufMut { - - /// Returns the number of bytes that can be written to the BufMut + /// Returns the number of bytes that can be written from the current + /// position until the end of the buffer is reached. + /// + /// This value is greater than or equal to the length of the slice returned + /// by `bytes_mut`. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// use std::io::Cursor; + /// + /// let mut dst = [0; 10]; + /// let mut buf = Cursor::new(&mut dst[..]); + /// + /// assert_eq!(10, buf.remaining_mut()); + /// buf.put("hello"); + /// + /// assert_eq!(5, buf.remaining_mut()); + /// ``` fn remaining_mut(&self) -> usize; /// Advance the internal cursor of the BufMut + /// + /// The next call to `bytes_mut` will return a slice starting `cnt` bytes + /// further into the underlying buffer. + /// + /// This function is unsafe because there is no guarantee that the bytes + /// being advanced to have been initialized. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = Vec::with_capacity(16); + /// + /// unsafe { + /// buf.bytes_mut()[0] = b'h'; + /// buf.bytes_mut()[1] = b'e'; + /// + /// buf.advance_mut(2); + /// + /// buf.bytes_mut()[0] = b'l'; + /// buf.bytes_mut()[1..3].copy_from_slice(b"lo"); + /// + /// buf.advance_mut(3); + /// } + /// + /// assert_eq!(5, buf.len()); + /// assert_eq!(buf, b"hello"); + /// ``` + /// + /// # Panics + /// + /// This function can panic if `cnt > self.remaining_mut()`. unsafe fn advance_mut(&mut self, cnt: usize); - /// Returns true iff there is any more space for bytes to be written + /// Returns true if there is space in `self` for more bytes. + /// + /// This is equivalent to `self.remaining_mut() != 0`. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// use std::io::Cursor; + /// + /// let mut dst = [0; 5]; + /// let mut buf = Cursor::new(&mut dst); + /// + /// assert!(buf.has_remaining_mut()); + /// + /// buf.put("hello"); + /// + /// assert!(!buf.has_remaining_mut()); + /// ``` fn has_remaining_mut(&self) -> bool { self.remaining_mut() > 0 } /// Returns a mutable slice starting at the current BufMut position and of - /// length between 0 and `BufMut::remaining()`. + /// length between 0 and `BufMut::remaining_mut()`. + /// + /// This is a lower level function. Most operations are done with other + /// functions. /// /// The returned byte slice may represent uninitialized memory. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = Vec::with_capacity(16); + /// + /// unsafe { + /// buf.bytes_mut()[0] = b'h'; + /// buf.bytes_mut()[1] = b'e'; + /// + /// buf.advance_mut(2); + /// + /// buf.bytes_mut()[0] = b'l'; + /// buf.bytes_mut()[1..3].copy_from_slice(b"lo"); + /// + /// buf.advance_mut(3); + /// } + /// + /// assert_eq!(5, buf.len()); + /// assert_eq!(buf, b"hello"); + /// ``` unsafe fn bytes_mut(&mut self) -> &mut [u8]; - /// Copies bytes from `src` into `self` + /// Transfer bytes into `self` from `src` and advance the cursor by the + /// number of bytes written. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// + /// let mut buf = vec![]; + /// + /// buf.put(b'h'); + /// buf.put(&b"ello"[..]); + /// buf.put(" world"); + /// + /// assert_eq!(buf, b"hello world"); + /// ``` /// /// # Panics /// - /// Panics if `self` does not have enough capacity to copy all the data - /// from `src` + /// Panics if `self` does not have enough capacity to contain `src`. fn put<S: Source>(&mut self, src: S) where Self: Sized { - src.source(self); + src.copy_to_buf(self); } - /// Copies bytes from the given slice into the `BufMut` and advance the - /// cursor by the number of bytes written. - /// Returns the number of bytes written. + /// Transfer bytes into `self` from `src` and advance the cursor by the + /// number of bytes written. + /// + /// `self` must have enough remaining capacity to contain all of `src`. /// /// ``` /// use bytes::BufMut; @@ -597,85 +727,273 @@ pub trait BufMut { } } - /// Writes an unsigned 16 bit integer to the BufMut. + /// Writes an unsigned 16 bit integer to `self` in the specified byte order. + /// + /// The current position is advanced by 2. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, BigEndian}; + /// + /// let mut buf = vec![]; + /// buf.put_u16::<BigEndian>(0x0809); + /// assert_eq!(buf, b"\x08\x09"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. fn put_u16<T: ByteOrder>(&mut self, n: u16) { let mut buf = [0; 2]; T::write_u16(&mut buf, n); self.put_slice(&buf) } - /// Writes a signed 16 bit integer to the BufMut. + /// Writes a signed 16 bit integer to `self` in the specified byte order. + /// + /// The current position is advanced by 2. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, BigEndian}; + /// + /// let mut buf = vec![]; + /// buf.put_i16::<BigEndian>(0x0809); + /// assert_eq!(buf, b"\x08\x09"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. fn put_i16<T: ByteOrder>(&mut self, n: i16) { let mut buf = [0; 2]; T::write_i16(&mut buf, n); self.put_slice(&buf) } - /// Writes an unsigned 32 bit integer to the BufMut. + /// Writes an unsigned 32 bit integer to `self` in the specified byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, BigEndian}; + /// + /// let mut buf = vec![]; + /// buf.put_u32::<BigEndian>(0x0809A0A1); + /// assert_eq!(buf, b"\x08\x09\xA0\xA1"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. fn put_u32<T: ByteOrder>(&mut self, n: u32) { let mut buf = [0; 4]; T::write_u32(&mut buf, n); self.put_slice(&buf) } - /// Writes a signed 32 bit integer to the BufMut. + /// Writes a signed 32 bit integer to `self` in the specified byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, BigEndian}; + /// + /// let mut buf = vec![]; + /// buf.put_i32::<BigEndian>(0x0809A0A1); + /// assert_eq!(buf, b"\x08\x09\xA0\xA1"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. fn put_i32<T: ByteOrder>(&mut self, n: i32) { let mut buf = [0; 4]; T::write_i32(&mut buf, n); self.put_slice(&buf) } - /// Writes an unsigned 64 bit integer to the BufMut. + /// Writes an unsigned 64 bit integer to `self` in the specified byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, BigEndian}; + /// + /// let mut buf = vec![]; + /// buf.put_u64::<BigEndian>(0x0102030405060708); + /// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. fn put_u64<T: ByteOrder>(&mut self, n: u64) { let mut buf = [0; 8]; T::write_u64(&mut buf, n); self.put_slice(&buf) } - /// Writes a signed 64 bit integer to the BufMut. + /// Writes a signed 64 bit integer to `self` in the specified byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, BigEndian}; + /// + /// let mut buf = vec![]; + /// buf.put_i64::<BigEndian>(0x0102030405060708); + /// assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. fn put_i64<T: ByteOrder>(&mut self, n: i64) { let mut buf = [0; 8]; T::write_i64(&mut buf, n); self.put_slice(&buf) } - /// Writes an unsigned n-bytes integer to the BufMut. + /// Writes an unsigned n-byte integer to `self` in the specified byte order. + /// + /// The current position is advanced by `nbytes`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, BigEndian}; + /// + /// let mut buf = vec![]; + /// buf.put_uint::<BigEndian>(0x010203, 3); + /// assert_eq!(buf, b"\x01\x02\x03"); + /// ``` + /// + /// # Panics /// - /// If the given integer is not representable in the given number of bytes, - /// this method panics. If `nbytes > 8`, this method panics. + /// This function panics if there is not enough remaining capacity in + /// `self`. fn put_uint<T: ByteOrder>(&mut self, n: u64, nbytes: usize) { let mut buf = [0; 8]; T::write_uint(&mut buf, n, nbytes); self.put_slice(&buf[0..nbytes]) } - /// Writes a signed n-bytes integer to the BufMut. + /// Writes a signed n-byte integer to `self` in the specified byte order. /// - /// If the given integer is not representable in the given number of bytes, - /// this method panics. If `nbytes > 8`, this method panics. + /// The current position is advanced by `nbytes`. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, BigEndian}; + /// + /// let mut buf = vec![]; + /// buf.put_int::<BigEndian>(0x010203, 3); + /// assert_eq!(buf, b"\x01\x02\x03"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. fn put_int<T: ByteOrder>(&mut self, n: i64, nbytes: usize) { let mut buf = [0; 8]; T::write_int(&mut buf, n, nbytes); self.put_slice(&buf[0..nbytes]) } - /// Writes a IEEE754 single-precision (4 bytes) floating point number to - /// the BufMut. + /// Writes an IEEE754 single-precision (4 bytes) floating point number to + /// `self` in the specified byte order. + /// + /// The current position is advanced by 4. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, BigEndian}; + /// + /// let mut buf = vec![]; + /// buf.put_f32::<BigEndian>(1.2f32); + /// assert_eq!(buf, b"\x3F\x99\x99\x9A"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. fn put_f32<T: ByteOrder>(&mut self, n: f32) { let mut buf = [0; 4]; T::write_f32(&mut buf, n); self.put_slice(&buf) } - /// Writes a IEEE754 double-precision (8 bytes) floating point number to - /// the BufMut. + /// Writes an IEEE754 double-precision (8 bytes) floating point number to + /// `self` in the specified byte order. + /// + /// The current position is advanced by 8. + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, BigEndian}; + /// + /// let mut buf = vec![]; + /// buf.put_f64::<BigEndian>(1.2f64); + /// assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33"); + /// ``` + /// + /// # Panics + /// + /// This function panics if there is not enough remaining capacity in + /// `self`. fn put_f64<T: ByteOrder>(&mut self, n: f64) { let mut buf = [0; 8]; T::write_f64(&mut buf, n); self.put_slice(&buf) } - /// Creates a "by reference" adaptor for this instance of BufMut + /// Creates a "by reference" adaptor for this instance of `BufMut`. + /// + /// The returned adapter also implements `BufMut` and will simply borrow + /// `self`. + /// + /// # Examples + /// + /// ``` + /// use bytes::BufMut; + /// use std::io; + /// + /// let mut buf = vec![]; + /// + /// { + /// let mut reference = buf.by_ref(); + /// + /// // Adapt reference to `std::io::Write`. + /// let mut writer = reference.writer(); + /// + /// // Use the buffer as a writter + /// io::Write::write(&mut writer, &b"hello world"[..]).unwrap(); + /// } // drop our &mut reference so that we can use `buf` again + /// + /// assert_eq!(buf, &b"hello world"[..]); + /// ``` fn by_ref(&mut self) -> &mut Self where Self: Sized { self } @@ -695,33 +1013,62 @@ pub trait BufMut { /// Conversion into a `Buf` /// -/// Usually, `IntoBuf` is implemented on references of types and not directly -/// on the types themselves. For example, `IntoBuf` is implemented for `&'a -/// Vec<u8>` and not `Vec<u8>` directly. +/// An `IntoBuf` implementation defines how to convert a value into a `Buf`. +/// This is common for types that represent byte storage of some kind. `IntoBuf` +/// may be implemented directly for types or on references for those types. +/// +/// # Examples +/// +/// ``` +/// use bytes::{Buf, IntoBuf, BigEndian}; +/// +/// let bytes = b"\x00\x01hello world"; +/// let mut buf = bytes.into_buf(); +/// +/// assert_eq!(1, buf.get_u16::<BigEndian>()); +/// +/// let mut rest = [0; 11]; +/// buf.copy_to_slice(&mut rest); +/// +/// assert_eq!(b"hello world", &rest); +/// ``` pub trait IntoBuf { /// The `Buf` type that `self` is being converted into type Buf: Buf; /// Creates a `Buf` from a value. + /// + /// # Examples + /// + /// ``` + /// use bytes::{Buf, IntoBuf, BigEndian}; + /// + /// let bytes = b"\x00\x01hello world"; + /// let mut buf = bytes.into_buf(); + /// + /// assert_eq!(1, buf.get_u16::<BigEndian>()); + /// + /// let mut rest = [0; 11]; + /// buf.copy_to_slice(&mut rest); + /// + /// assert_eq!(b"hello world", &rest); + /// ``` fn into_buf(self) -> Self::Buf; } impl<'a> IntoBuf for &'a [u8] { type Buf = io::Cursor<&'a [u8]>; - /// Creates a buffer from a value fn into_buf(self) -> Self::Buf { io::Cursor::new(self) } } -// Kind of annoying... -impl<'a> IntoBuf for &'a &'static [u8] { - type Buf = io::Cursor<&'static [u8]>; +impl<'a> IntoBuf for &'a str { + type Buf = io::Cursor<&'a [u8]>; - /// Creates a buffer from a value fn into_buf(self) -> Self::Buf { - io::Cursor::new(self) + self.as_bytes().into_buf() } } @@ -733,6 +1080,24 @@ impl IntoBuf for Vec<u8> { } } +// Kind of annoying... but this impl is required to allow passing `&'static +// [u8]` where for<'a> &'a T: IntoBuf is required. +impl<'a> IntoBuf for &'a &'static [u8] { + type Buf = io::Cursor<&'static [u8]>; + + fn into_buf(self) -> Self::Buf { + io::Cursor::new(self) + } +} + +impl<'a> IntoBuf for &'a &'static str { + type Buf = io::Cursor<&'static [u8]>; + + fn into_buf(self) -> Self::Buf { + self.as_bytes().into_buf() + } +} + impl<'a> IntoBuf for &'a Vec<u8> { type Buf = io::Cursor<&'a [u8]>; @@ -741,6 +1106,22 @@ impl<'a> IntoBuf for &'a Vec<u8> { } } +impl IntoBuf for String { + type Buf = io::Cursor<Vec<u8>>; + + fn into_buf(self) -> Self::Buf { + self.into_bytes().into_buf() + } +} + +impl<'a> IntoBuf for &'a String { + type Buf = io::Cursor<&'a [u8]>; + + fn into_buf(self) -> Self::Buf { + self.as_bytes().into_buf() + } +} + impl IntoBuf for () { type Buf = io::Cursor<&'static [u8]>; @@ -765,50 +1146,120 @@ impl<'a> IntoBuf for &'a () { /// A value that writes bytes from itself into a `BufMut`. +/// +/// Values that implement `Source` are used as an argument to +/// [`BufMut::put`](trait.BufMut.html#method.put). +/// +/// # Examples +/// +/// ``` +/// use bytes::{BufMut, Source}; +/// +/// struct Repeat { +/// num: usize, +/// str: String, +/// } +/// +/// impl Source for Repeat { +/// fn copy_to_buf<B: BufMut>(self, buf: &mut B) { +/// for _ in 0..self.num { +/// buf.put(&self.str); +/// } +/// } +/// } +/// +/// let mut dst = vec![]; +/// dst.put(Repeat { +/// num: 3, +/// str: "hello".into(), +/// }); +/// +/// assert_eq!(*dst, b"hellohellohello"[..]); +/// ``` pub trait Source { /// Copy data from self into destination buffer - fn source<B: BufMut>(self, buf: &mut B); + /// + /// # Examples + /// + /// ``` + /// use bytes::{BufMut, Source}; + /// + /// let mut dst = vec![]; + /// + /// "hello".copy_to_buf(&mut dst); + /// + /// assert_eq!(*dst, b"hello"[..]); + /// ``` + /// + /// # Panics + /// + /// This function panis if `buf` does not have enough capacity for `self`. + fn copy_to_buf<B: BufMut>(self, buf: &mut B); +} + +impl Source for Vec<u8> { + fn copy_to_buf<B: BufMut>(self, buf: &mut B) { + buf.put_slice(&self[..]); + } +} + +impl<'a> Source for &'a Vec<u8> { + fn copy_to_buf<B: BufMut>(self, buf: &mut B) { + buf.put_slice(&self[..]); + } } impl<'a> Source for &'a [u8] { - fn source<B: BufMut>(self, buf: &mut B) { + fn copy_to_buf<B: BufMut>(self, buf: &mut B) { buf.put_slice(self); } } +impl Source for String { + fn copy_to_buf<B: BufMut>(self, buf: &mut B) { + buf.put_slice(self.as_bytes()); + } +} + +impl<'a> Source for &'a String { + fn copy_to_buf<B: BufMut>(self, buf: &mut B) { + buf.put_slice(self.as_bytes()); + } +} + impl<'a> Source for &'a str { - fn source<B: BufMut>(self, buf: &mut B) { + fn copy_to_buf<B: BufMut>(self, buf: &mut B) { buf.put_slice(self.as_bytes()); } } impl Source for u8 { - fn source<B: BufMut>(self, buf: &mut B) { + fn copy_to_buf<B: BufMut>(self, buf: &mut B) { let src = [self]; buf.put_slice(&src); } } impl Source for i8 { - fn source<B: BufMut>(self, buf: &mut B) { + fn copy_to_buf<B: BufMut>(self, buf: &mut B) { buf.put_slice(&[self as u8]) } } impl Source for Bytes { - fn source<B: BufMut>(self, buf: &mut B) { - Source::source(self.as_ref(), buf); + fn copy_to_buf<B: BufMut>(self, buf: &mut B) { + Source::copy_to_buf(self.as_ref(), buf); } } impl<'a> Source for &'a Bytes { - fn source<B: BufMut>(self, buf: &mut B) { - Source::source(self.as_ref(), buf); + fn copy_to_buf<B: BufMut>(self, buf: &mut B) { + Source::copy_to_buf(self.as_ref(), buf); } } -impl<'a, T: Buf> Source for &'a mut T { - fn source<B: BufMut>(mut self, buf: &mut B) { +impl<T: Buf> Source for T { + fn copy_to_buf<B: BufMut>(mut self, buf: &mut B) { assert!(buf.remaining_mut() >= self.remaining()); while self.has_remaining() { @@ -839,8 +1290,8 @@ impl<'a, T: Buf> Source for &'a mut T { /// A `Buf` adapter which limits the bytes read from an underlying buffer. /// -/// This struct is generally created by calling `take()` on `Buf`. [More -/// detail](trait.Buf.html#method.take). +/// This struct is generally created by calling `take()` on `Buf`. See +/// documentation of [`take()`](trait.Buf.html#method.take) for more details. pub struct Take<T> { inner: T, limit: usize, @@ -848,28 +1299,117 @@ pub struct Take<T> { impl<T> Take<T> { /// Consumes this `Take`, returning the underlying value. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, BufMut}; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"hello world").take(2); + /// let mut dst = vec![]; + /// + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"he"[..]); + /// + /// let mut buf = buf.into_inner(); + /// + /// dst.clear(); + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"llo world"[..]); + /// ``` pub fn into_inner(self) -> T { self.inner } - /// Gets a reference to the underlying value in this `Take`. + /// Gets a reference to the underlying `Buf`. + /// + /// It is inadvisable to directly read from the underlying reader. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, BufMut}; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"hello world").take(2); + /// + /// assert_eq!(0, buf.get_ref().position()); + /// ``` pub fn get_ref(&self) -> &T { &self.inner } - /// Gets a mutable reference to the underlying value in this `Take`. + /// Gets a mutable reference to the underlying `Buf`. + /// + /// It is inadvisable to directly read from the underlying reader. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, BufMut}; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"hello world").take(2); + /// let mut dst = vec![]; + /// + /// buf.get_mut().set_position(2); + /// + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"ll"[..]); + /// ``` pub fn get_mut(&mut self) -> &mut T { &mut self.inner } - /// Returns the maximum number of bytes that are made available from the - /// underlying value. + /// Returns the maximum number of bytes that can be read. + /// + /// # Note + /// + /// If the inner `Buf` has fewer bytes than indicated by this method then + /// that is the actual number of available bytes. + /// + /// # Examples + /// + /// ```rust + /// use bytes::Buf; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"hello world").take(2); + /// + /// assert_eq!(2, buf.limit()); + /// assert_eq!(b'h', buf.get_u8()); + /// assert_eq!(1, buf.limit()); + /// ``` pub fn limit(&self) -> usize { self.limit } - /// Sets the maximum number of bytes that are made available from the - /// underlying value. + /// Sets the maximum number of bytes that can be read. + /// + /// # Note + /// + /// If the inner `Buf` has fewer bytes than `lim` then that is the actual + /// number of available bytes. + /// + /// # Examples + /// + /// ```rust + /// use bytes::{Buf, BufMut}; + /// use std::io::Cursor; + /// + /// let mut buf = Cursor::new(b"hello world").take(2); + /// let mut dst = vec![]; + /// + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"he"[..]); + /// + /// dst.clear(); + /// + /// buf.set_limit(3); + /// dst.put(&mut buf); + /// assert_eq!(*dst, b"llo"[..]); + /// ``` pub fn set_limit(&mut self, lim: usize) { self.limit = lim }