Skip to content

Commit ed4d78f

Browse files
Implement chunks_vectored for VecDeque<u8>
1 parent caf520a commit ed4d78f

File tree

2 files changed

+56
-3
lines changed

2 files changed

+56
-3
lines changed

src/buf/vec_deque.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
use alloc::collections::VecDeque;
2+
#[cfg(feature = "std")]
3+
use std::io;
24

35
use super::Buf;
46

@@ -16,6 +18,22 @@ impl Buf for VecDeque<u8> {
1618
}
1719
}
1820

21+
#[cfg(feature = "std")]
22+
fn chunks_vectored<'a>(&'a self, dst: &mut [io::IoSlice<'a>]) -> usize {
23+
if self.is_empty() || dst.is_empty() {
24+
return 0;
25+
}
26+
27+
let (s1, s2) = self.as_slices();
28+
dst[0] = io::IoSlice::new(s1);
29+
if s2.is_empty() || dst.len() == 1 {
30+
return 1;
31+
}
32+
33+
dst[1] = io::IoSlice::new(s2);
34+
2
35+
}
36+
1937
fn advance(&mut self, cnt: usize) {
2038
self.drain(..cnt);
2139
}

tests/test_buf.rs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#![warn(rust_2018_idioms)]
22

3+
use std::collections::VecDeque;
4+
35
use bytes::Buf;
46
#[cfg(feature = "std")]
57
use std::io::IoSlice;
@@ -58,9 +60,7 @@ fn test_bufs_vec() {
5860

5961
#[test]
6062
fn test_vec_deque() {
61-
use std::collections::VecDeque;
62-
63-
let mut buffer: VecDeque<u8> = VecDeque::new();
63+
let mut buffer = VecDeque::new();
6464
buffer.extend(b"hello world");
6565
assert_eq!(11, buffer.remaining());
6666
assert_eq!(b"hello world", buffer.chunk());
@@ -72,6 +72,41 @@ fn test_vec_deque() {
7272
assert_eq!(b"world piece", &out[..]);
7373
}
7474

75+
#[cfg(feature = "std")]
76+
#[test]
77+
fn test_vec_deque_vectored() {
78+
let mut buffer = VecDeque::new();
79+
buffer.reserve_exact(128);
80+
assert_eq!(buffer.chunks_vectored(&mut [IoSlice::new(&[])]), 0);
81+
82+
buffer.extend(0..64);
83+
buffer.drain(..32);
84+
buffer.extend(64..160);
85+
86+
assert_eq!(buffer.chunks_vectored(&mut []), 0);
87+
88+
let mut chunks = [IoSlice::new(&[]); 1];
89+
assert_eq!(buffer.chunks_vectored(&mut chunks), 1);
90+
assert!(!chunks[0].is_empty());
91+
let combined = chunks[0].iter().copied().collect::<Vec<u8>>();
92+
let expected = (32..160).take(chunks[0].len()).collect::<Vec<_>>();
93+
assert_eq!(combined, expected);
94+
95+
let mut chunks = [IoSlice::new(&[]); 2];
96+
assert_eq!(buffer.chunks_vectored(&mut chunks), 2);
97+
assert!(!chunks[0].is_empty());
98+
assert!(!chunks[1].is_empty());
99+
let combined = chunks
100+
.iter()
101+
.flat_map(|chunk| chunk.iter())
102+
.copied()
103+
.collect::<Vec<u8>>();
104+
let expected = (32..160).collect::<Vec<u8>>();
105+
assert_eq!(combined, expected);
106+
107+
assert_eq!(buffer.chunks_vectored(&mut [IoSlice::new(&[]); 8]), 2);
108+
}
109+
75110
#[allow(unused_allocation)] // This is intentional.
76111
#[test]
77112
fn test_deref_buf_forwards() {

0 commit comments

Comments
 (0)