Skip to content

Commit

Permalink
Implement Buf for std::io::Take<&[u8]>.
Browse files Browse the repository at this point in the history
  • Loading branch information
smarnach committed Dec 6, 2019
1 parent a490821 commit a1a7768
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/buf/buf_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,30 @@ impl Buf for &[u8] {
}
}

impl<'a> Buf for io::Take<&'a [u8]> {
#[inline]
fn remaining(&self) -> usize {
let len = self.get_ref().len() as u64;
let limit = self.limit();
// The smaller of the two values will always fit in usize.
cmp::min(len, limit) as usize
}

fn bytes(&self) -> &[u8] {
&self.get_ref()[..self.remaining()]
}

fn advance(&mut self, cnt: usize) {
let remaining = self.remaining();
assert!(cnt <= remaining);
// Use the actual number of remaining bytes as new limit, even if limit
// was greater than remaining before.
self.set_limit((remaining - cnt) as u64);
let slice = self.get_mut();
*slice = &slice[cnt..];
}
}

impl Buf for Option<[u8; 1]> {
fn remaining(&self) -> usize {
if self.is_some() {
Expand Down
38 changes: 38 additions & 0 deletions tests/test_buf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,41 @@ fn test_vec_deque() {
buffer.copy_to_slice(&mut out);
assert_eq!(b"world piece", &out[..]);
}

#[test]
fn test_take() {
// Pulling Read into the scope would result in a conflict between
// Buf::bytes() from Read::bytes().
let mut buf = std::io::Read::take(&b"hello world"[..], 5);
assert_eq!(buf.bytes(), b"hello");
assert_eq!(buf.remaining(), 5);

buf.advance(3);
assert_eq!(buf.bytes(), b"lo");
assert_eq!(buf.remaining(), 2);

buf.advance(2);
assert_eq!(buf.bytes(), b"");
assert_eq!(buf.remaining(), 0);
}

#[test]
#[should_panic]
fn test_take_advance_too_far() {
let mut buf = std::io::Read::take(&b"hello world"[..], 5);
buf.advance(10);
}

#[test]
fn test_take_limit_gt_length() {
// The byte array has only 11 bytes, but we take 15 bytes.
let mut buf = std::io::Read::take(&b"hello world"[..], 15);
assert_eq!(buf.remaining(), 11);
assert_eq!(buf.limit(), 15);

buf.advance(5);
assert_eq!(buf.remaining(), 6);
// The limit is reduced my more than the number of bytes we advanced, to
// the actual number of remaining bytes in the buffer.
assert_eq!(buf.limit(), 6);
}

0 comments on commit a1a7768

Please sign in to comment.