scuffle_bytes_util/
bytes_cursor.rsuse std::io;
use bytes::Bytes;
pub type BytesCursor = io::Cursor<Bytes>;
pub trait BytesCursorExt {
fn extract_remaining(&mut self) -> Bytes;
fn extract_bytes(&mut self, size: usize) -> io::Result<Bytes>;
}
fn remaining(cursor: &BytesCursor) -> usize {
cursor.get_ref().len().saturating_sub(cursor.position() as usize)
}
impl BytesCursorExt for BytesCursor {
fn extract_remaining(&mut self) -> Bytes {
self.extract_bytes(remaining(self)).unwrap_or_default()
}
fn extract_bytes(&mut self, size: usize) -> io::Result<Bytes> {
if size == 0 {
return Ok(Bytes::new());
}
if size > remaining(self) {
return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "not enough bytes"));
}
let position = self.position() as usize;
let slice = self.get_ref().slice(position..position + size);
self.set_position((position + size) as u64);
Ok(slice)
}
}
#[cfg(test)]
#[cfg_attr(all(test, coverage_nightly), coverage(off))]
mod tests {
use super::*;
#[test]
fn test_bytes_cursor_extract_remaining() {
let mut cursor = io::Cursor::new(Bytes::from_static(&[1, 2, 3, 4, 5]));
let remaining = cursor.extract_remaining();
assert_eq!(remaining, Bytes::from_static(&[1, 2, 3, 4, 5]));
}
#[test]
fn test_bytes_cursor_extract_bytes() {
let mut cursor = io::Cursor::new(Bytes::from_static(&[1, 2, 3, 4, 5]));
let bytes = cursor.extract_bytes(3).unwrap();
assert_eq!(bytes, Bytes::from_static(&[1, 2, 3]));
assert_eq!(remaining(&cursor), 2);
let bytes = cursor.extract_bytes(2).unwrap();
assert_eq!(bytes, Bytes::from_static(&[4, 5]));
assert_eq!(remaining(&cursor), 0);
let bytes = cursor.extract_bytes(1).unwrap_err();
assert_eq!(bytes.kind(), io::ErrorKind::UnexpectedEof);
let bytes = cursor.extract_bytes(0).unwrap();
assert_eq!(bytes, Bytes::from_static(&[]));
assert_eq!(remaining(&cursor), 0);
let bytes = cursor.extract_remaining();
assert_eq!(bytes, Bytes::from_static(&[]));
assert_eq!(remaining(&cursor), 0);
}
#[test]
fn seek_out_of_bounds() {
let mut cursor = io::Cursor::new(Bytes::from_static(&[1, 2, 3, 4, 5]));
cursor.set_position(10);
assert_eq!(remaining(&cursor), 0);
let bytes = cursor.extract_remaining();
assert_eq!(bytes, Bytes::from_static(&[]));
let bytes = cursor.extract_bytes(1);
assert_eq!(bytes.unwrap_err().kind(), io::ErrorKind::UnexpectedEof);
let bytes = cursor.extract_bytes(0);
assert_eq!(bytes.unwrap(), Bytes::from_static(&[]));
}
}