Skip to content

Commit a1a7768

Browse files
committed
Implement Buf for std::io::Take<&[u8]>.
1 parent a490821 commit a1a7768

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

src/buf/buf_impl.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,30 @@ impl Buf for &[u8] {
864864
}
865865
}
866866

867+
impl<'a> Buf for io::Take<&'a [u8]> {
868+
#[inline]
869+
fn remaining(&self) -> usize {
870+
let len = self.get_ref().len() as u64;
871+
let limit = self.limit();
872+
// The smaller of the two values will always fit in usize.
873+
cmp::min(len, limit) as usize
874+
}
875+
876+
fn bytes(&self) -> &[u8] {
877+
&self.get_ref()[..self.remaining()]
878+
}
879+
880+
fn advance(&mut self, cnt: usize) {
881+
let remaining = self.remaining();
882+
assert!(cnt <= remaining);
883+
// Use the actual number of remaining bytes as new limit, even if limit
884+
// was greater than remaining before.
885+
self.set_limit((remaining - cnt) as u64);
886+
let slice = self.get_mut();
887+
*slice = &slice[cnt..];
888+
}
889+
}
890+
867891
impl Buf for Option<[u8; 1]> {
868892
fn remaining(&self) -> usize {
869893
if self.is_some() {

tests/test_buf.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,41 @@ fn test_vec_deque() {
6969
buffer.copy_to_slice(&mut out);
7070
assert_eq!(b"world piece", &out[..]);
7171
}
72+
73+
#[test]
74+
fn test_take() {
75+
// Pulling Read into the scope would result in a conflict between
76+
// Buf::bytes() from Read::bytes().
77+
let mut buf = std::io::Read::take(&b"hello world"[..], 5);
78+
assert_eq!(buf.bytes(), b"hello");
79+
assert_eq!(buf.remaining(), 5);
80+
81+
buf.advance(3);
82+
assert_eq!(buf.bytes(), b"lo");
83+
assert_eq!(buf.remaining(), 2);
84+
85+
buf.advance(2);
86+
assert_eq!(buf.bytes(), b"");
87+
assert_eq!(buf.remaining(), 0);
88+
}
89+
90+
#[test]
91+
#[should_panic]
92+
fn test_take_advance_too_far() {
93+
let mut buf = std::io::Read::take(&b"hello world"[..], 5);
94+
buf.advance(10);
95+
}
96+
97+
#[test]
98+
fn test_take_limit_gt_length() {
99+
// The byte array has only 11 bytes, but we take 15 bytes.
100+
let mut buf = std::io::Read::take(&b"hello world"[..], 15);
101+
assert_eq!(buf.remaining(), 11);
102+
assert_eq!(buf.limit(), 15);
103+
104+
buf.advance(5);
105+
assert_eq!(buf.remaining(), 6);
106+
// The limit is reduced my more than the number of bytes we advanced, to
107+
// the actual number of remaining bytes in the buffer.
108+
assert_eq!(buf.limit(), 6);
109+
}

0 commit comments

Comments
 (0)