Add Buf::copy_to_bytes(len) (#439)

This method replaces `Buf::to_bytes()`, providing a method that copies a
subset of the remaining buffer into a `Bytes` value. As this is strictly
more flexible, `to_bytes()` is removed.

Fixes: #129, #398
This commit is contained in:
Carl Lerche
2020-10-20 11:00:35 -07:00
committed by GitHub
parent 5866839e45
commit 39de065a1e
6 changed files with 48 additions and 17 deletions
+17 -9
View File
@@ -795,20 +795,28 @@ pub trait Buf {
f64::from_bits(Self::get_u64_le(self)) f64::from_bits(Self::get_u64_le(self))
} }
/// Consumes remaining bytes inside self and returns new instance of `Bytes` /// Consumes `len` bytes inside self and returns new instance of `Bytes`
/// with this data.
///
/// This function may be optimized by the underlying type to avoid actual
/// copies. For example, `Bytes` implementation will do a shallow copy
/// (ref-count increment).
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// use bytes::Buf; /// use bytes::Buf;
/// ///
/// let bytes = (&b"hello world"[..]).to_bytes(); /// let bytes = (&b"hello world"[..]).copy_to_bytes(5);
/// assert_eq!(&bytes[..], &b"hello world"[..]); /// assert_eq!(&bytes[..], &b"hello"[..]);
/// ``` /// ```
fn to_bytes(&mut self) -> crate::Bytes { fn copy_to_bytes(&mut self, len: usize) -> crate::Bytes {
use super::BufMut; use super::BufMut;
let mut ret = crate::BytesMut::with_capacity(self.remaining());
ret.put(self); assert!(len <= self.remaining(), "`len` greater than remaining");
let mut ret = crate::BytesMut::with_capacity(len);
ret.put(self.take(len));
ret.freeze() ret.freeze()
} }
@@ -852,7 +860,7 @@ pub trait Buf {
/// ///
/// let mut chain = b"hello "[..].chain(&b"world"[..]); /// let mut chain = b"hello "[..].chain(&b"world"[..]);
/// ///
/// let full = chain.to_bytes(); /// let full = chain.copy_to_bytes(11);
/// assert_eq!(full.bytes(), b"hello world"); /// assert_eq!(full.bytes(), b"hello world");
/// ``` /// ```
fn chain<U: Buf>(self, next: U) -> Chain<Self, U> fn chain<U: Buf>(self, next: U) -> Chain<Self, U>
@@ -993,8 +1001,8 @@ macro_rules! deref_forward_buf {
(**self).get_int_le(nbytes) (**self).get_int_le(nbytes)
} }
fn to_bytes(&mut self) -> crate::Bytes { fn copy_to_bytes(&mut self, len: usize) -> crate::Bytes {
(**self).to_bytes() (**self).copy_to_bytes(len)
} }
}; };
} }
+3 -3
View File
@@ -21,7 +21,7 @@ use std::io::IoSlice;
/// let mut buf = (&b"hello "[..]) /// let mut buf = (&b"hello "[..])
/// .chain(&b"world"[..]); /// .chain(&b"world"[..]);
/// ///
/// let full: Bytes = buf.to_bytes(); /// let full: Bytes = buf.copy_to_bytes(11);
/// assert_eq!(full[..], b"hello world"[..]); /// assert_eq!(full[..], b"hello world"[..]);
/// ``` /// ```
/// ///
@@ -68,7 +68,7 @@ impl<T, U> Chain<T, U> {
/// ///
/// buf.first_mut().advance(1); /// buf.first_mut().advance(1);
/// ///
/// let full = buf.to_bytes(); /// let full = buf.copy_to_bytes(9);
/// assert_eq!(full, b"elloworld"[..]); /// assert_eq!(full, b"elloworld"[..]);
/// ``` /// ```
pub fn first_mut(&mut self) -> &mut T { pub fn first_mut(&mut self) -> &mut T {
@@ -103,7 +103,7 @@ impl<T, U> Chain<T, U> {
/// ///
/// buf.last_mut().advance(1); /// buf.last_mut().advance(1);
/// ///
/// let full = buf.to_bytes(); /// let full = buf.copy_to_bytes(10);
/// assert_eq!(full, b"hello orld"[..]); /// assert_eq!(full, b"hello orld"[..]);
/// ``` /// ```
pub fn last_mut(&mut self) -> &mut U { pub fn last_mut(&mut self) -> &mut U {
+8 -2
View File
@@ -548,8 +548,14 @@ impl Buf for Bytes {
} }
} }
fn to_bytes(&mut self) -> crate::Bytes { fn copy_to_bytes(&mut self, len: usize) -> crate::Bytes {
core::mem::replace(self, Bytes::new()) if len == self.remaining() {
core::mem::replace(self, Bytes::new())
} else {
let ret = self.slice(..len);
self.advance(len);
ret
}
} }
} }
+2 -2
View File
@@ -961,8 +961,8 @@ impl Buf for BytesMut {
} }
} }
fn to_bytes(&mut self) -> crate::Bytes { fn copy_to_bytes(&mut self, len: usize) -> crate::Bytes {
self.split().freeze() self.split_to(len).freeze()
} }
} }
+17
View File
@@ -101,3 +101,20 @@ fn test_deref_buf_forwards() {
assert_eq!((Box::new(Special) as Box<dyn Buf>).get_u8(), b'x'); assert_eq!((Box::new(Special) as Box<dyn Buf>).get_u8(), b'x');
assert_eq!(Box::new(Special).get_u8(), b'x'); assert_eq!(Box::new(Special).get_u8(), b'x');
} }
#[test]
fn copy_to_bytes_less() {
let mut buf = &b"hello world"[..];
let bytes = buf.copy_to_bytes(5);
assert_eq!(bytes, &b"hello"[..]);
assert_eq!(buf, &b" world"[..])
}
#[test]
#[should_panic]
fn copy_to_bytes_overflow() {
let mut buf = &b"hello world"[..];
let _bytes = buf.copy_to_bytes(12);
}
+1 -1
View File
@@ -9,7 +9,7 @@ fn collect_two_bufs() {
let a = Bytes::from(&b"hello"[..]); let a = Bytes::from(&b"hello"[..]);
let b = Bytes::from(&b"world"[..]); let b = Bytes::from(&b"world"[..]);
let res = a.chain(b).to_bytes(); let res = a.chain(b).copy_to_bytes(10);
assert_eq!(res, &b"helloworld"[..]); assert_eq!(res, &b"helloworld"[..]);
} }