Skip to content

Commit 3e0541d

Browse files
committed
Implement Buf for std::io::Take<&[u8]>.
1 parent 456221d commit 3e0541d

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

src/buf/buf.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,30 @@ impl<T: AsRef<[u8]>> Buf for io::Cursor<T> {
11201120
}
11211121
}
11221122

1123+
impl<'a> Buf for io::Take<&'a [u8]> {
1124+
#[inline]
1125+
fn remaining(&self) -> usize {
1126+
let len = self.get_ref().len() as u64;
1127+
let limit = self.limit();
1128+
// The smaller of the two values will always fit in usize.
1129+
cmp::min(len, limit) as usize
1130+
}
1131+
1132+
fn bytes(&self) -> &[u8] {
1133+
&self.get_ref()[..self.remaining()]
1134+
}
1135+
1136+
fn advance(&mut self, cnt: usize) {
1137+
let remaining = self.remaining();
1138+
assert!(cnt <= remaining);
1139+
// Use the actual number of remaining bytes as new limit, even if limit
1140+
// was greater than remaining before.
1141+
self.set_limit((remaining - cnt) as u64);
1142+
let slice = self.get_mut();
1143+
*slice = &slice[cnt..];
1144+
}
1145+
}
1146+
11231147
impl Buf for Option<[u8; 1]> {
11241148
fn remaining(&self) -> usize {
11251149
if self.is_some() {

tests/test_buf.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,41 @@ fn test_bufs_vec() {
5656

5757
assert_eq!(1, buf.bytes_vec(&mut dst[..]));
5858
}
59+
60+
#[test]
61+
fn test_take() {
62+
// Pulling Read into the scope would result in a conflict between
63+
// Buf::bytes() from Read::bytes().
64+
let mut buf = std::io::Read::take(&b"hello world"[..], 5);
65+
assert_eq!(buf.bytes(), b"hello");
66+
assert_eq!(buf.remaining(), 5);
67+
68+
buf.advance(3);
69+
assert_eq!(buf.bytes(), b"lo");
70+
assert_eq!(buf.remaining(), 2);
71+
72+
buf.advance(2);
73+
assert_eq!(buf.bytes(), b"");
74+
assert_eq!(buf.remaining(), 0);
75+
}
76+
77+
#[test]
78+
#[should_panic]
79+
fn test_take_advance_too_far() {
80+
let mut buf = std::io::Read::take(&b"hello world"[..], 5);
81+
buf.advance(10);
82+
}
83+
84+
#[test]
85+
fn test_take_limit_gt_length() {
86+
// The byte array has only 11 bytes, but we take 15 bytes.
87+
let mut buf = std::io::Read::take(&b"hello world"[..], 15);
88+
assert_eq!(buf.remaining(), 11);
89+
assert_eq!(buf.limit(), 15);
90+
91+
buf.advance(5);
92+
assert_eq!(buf.remaining(), 6);
93+
// The limit is reduced my more than the number of bytes we advanced, to
94+
// the actual number of remaining bytes in the buffer.
95+
assert_eq!(buf.limit(), 6);
96+
}

0 commit comments

Comments
 (0)