diff --git a/src/buf/vec_deque.rs b/src/buf/vec_deque.rs index 263167e83..55d5636b1 100644 --- a/src/buf/vec_deque.rs +++ b/src/buf/vec_deque.rs @@ -1,4 +1,6 @@ use alloc::collections::VecDeque; +#[cfg(feature = "std")] +use std::io; use super::Buf; @@ -16,6 +18,22 @@ impl Buf for VecDeque { } } + #[cfg(feature = "std")] + fn chunks_vectored<'a>(&'a self, dst: &mut [io::IoSlice<'a>]) -> usize { + if self.is_empty() || dst.is_empty() { + return 0; + } + + let (s1, s2) = self.as_slices(); + dst[0] = io::IoSlice::new(s1); + if s2.is_empty() || dst.len() == 1 { + return 1; + } + + dst[1] = io::IoSlice::new(s2); + 2 + } + fn advance(&mut self, cnt: usize) { self.drain(..cnt); } diff --git a/tests/test_buf.rs b/tests/test_buf.rs index 3940f9247..7ec1ee6fe 100644 --- a/tests/test_buf.rs +++ b/tests/test_buf.rs @@ -1,5 +1,7 @@ #![warn(rust_2018_idioms)] +use std::collections::VecDeque; + use bytes::Buf; #[cfg(feature = "std")] use std::io::IoSlice; @@ -58,9 +60,7 @@ fn test_bufs_vec() { #[test] fn test_vec_deque() { - use std::collections::VecDeque; - - let mut buffer: VecDeque = VecDeque::new(); + let mut buffer = VecDeque::new(); buffer.extend(b"hello world"); assert_eq!(11, buffer.remaining()); assert_eq!(b"hello world", buffer.chunk()); @@ -72,6 +72,37 @@ fn test_vec_deque() { assert_eq!(b"world piece", &out[..]); } +#[cfg(feature = "std")] +#[test] +fn test_vec_deque_vectored() { + let mut buffer = VecDeque::with_capacity(32); + assert_eq!(buffer.chunks_vectored(&mut [IoSlice::new(&[])]), 0); + + buffer.extend(b"hello world"); + buffer.drain(.."hello ".len()); + buffer.extend(b" hello again it's working!"); + + assert_eq!(buffer.chunks_vectored(&mut []), 0); + + let mut chunks = [IoSlice::new(&[]); 1]; + assert_eq!(buffer.chunks_vectored(&mut chunks), 1); + assert!(!chunks[0].is_empty()); + assert!(b"world hello again it's working!".starts_with(&chunks[0])); + + let mut chunks = [IoSlice::new(&[]); 2]; + assert_eq!(buffer.chunks_vectored(&mut chunks), 2); + assert!(!chunks[0].is_empty()); + assert!(!chunks[1].is_empty()); + let combined = chunks + .iter() + .flat_map(|chunk| chunk.iter()) + .copied() + .collect::>(); + assert_eq!(combined, b"world hello again it's working!"); + + assert_eq!(buffer.chunks_vectored(&mut [IoSlice::new(&[]); 8]), 2); +} + #[allow(unused_allocation)] // This is intentional. #[test] fn test_deref_buf_forwards() {