message: perf(body): specialize BufList::copy_to_bytes
  Some implementations of the Buf trait have an optimized version (for
  example Bytes) of copy_to_bytes, opportunistically use that one.
diff: use std::collections::VecDeque;
  use std::io::IoSlice;
  -use bytes::Buf;
  +use bytes::{Buf, BufMut, Bytes, BytesMut};
  pub(crate) struct BufList<T> {
  bufs: VecDeque<T>,
  @@ -70,4 +70,82 @@ impl<T: Buf> Buf for BufList<T> {
  }
  vecs
  }
  +
  + #[inline]
  + fn copy_to_bytes(&mut self, len: usize) -> Bytes {
  + // Our inner buffer may have an optimized version of copy_to_bytes, and if the whole
  + // request can be fulfilled by the front buffer, we can take advantage.
  + match self.bufs.front_mut() {
  + Some(front) if front.remaining() == len => {
  + let b = front.copy_to_bytes(len);
  + self.bufs.pop_front();
  + b
  + }
  + Some(front) if front.remaining() > len => front.copy_to_bytes(len),
  + _ => {
  + assert!(len <= self.remaining(), "`len` greater than remaining");
  + let mut bm = BytesMut::with_capacity(len);
  + bm.put(self.take(len));
  + bm.freeze()
  + }
  + }
  + }
  +}
  +
  +#[cfg(test)]
  +mod tests {
  + use std::ptr;
  +
  + use super::*;
  +
  + fn hello_world_buf() -> BufList<Bytes> {
  + BufList {
  + bufs: vec![Bytes::from("Hello"), Bytes::from(" "), Bytes::from("World")].into(),
  + }
  + }
  +
  + #[test]
  + fn to_bytes_shorter() {
  + let mut bufs = hello_world_buf();
  + let old_ptr = bufs.chunk().as_ptr();
  + let start = bufs.copy_to_bytes(4);
  + assert_eq!(start, "Hell");
  + assert!(ptr::eq(old_ptr, start.as_ptr()));
  + assert_eq!(bufs.chunk(), b"o");
  + assert!(ptr::eq(old_ptr.wrapping_add(4), bufs.chunk().as_ptr()));
  + assert_eq!(bufs.remaining(), 7);
  + }
  +
  + #[test]
  + fn to_bytes_eq() {
  + let mut bufs = hello_world_buf();
  + let old_ptr = bufs.chunk().as_ptr();
  + let start = bufs.copy_to_bytes(5);
  + assert_eq!(start, "Hello");
  + assert!(ptr::eq(old_ptr, start.as_ptr()));
  + assert_eq!(bufs.chunk(), b" ");
  + assert_eq!(bufs.remaining(), 6);
  + }
  +
  + #[test]
  + fn to_bytes_longer() {
  + let mut bufs = hello_world_buf();
  + let start = bufs.copy_to_bytes(7);
  + assert_eq!(start, "Hello W");
  + assert_eq!(bufs.remaining(), 4);
  + }
  +
  + #[test]
  + fn one_long_buf_to_bytes() {
  + let mut buf = BufList::new();
  + buf.push(b"Hello World" as &[_]);
  + assert_eq!(buf.copy_to_bytes(5), "Hello");
  + assert_eq!(buf.chunk(), b" World");
  + }
  +
  + #[test]
  + #[should_panic(expected = "`len` greater than remaining")]
  + fn buf_to_bytes_too_many() {
  + hello_world_buf().copy_to_bytes(42);
  + }
  }
  