pub trait ReadToTimeout {
fn read_to_timeout(&mut self, buf: &mut Vec<u8>) -> std::io::Result<usize>;
fn read_to_timeout_or_bytes(
&mut self,
buf: &mut Vec<u8>,
max_byte: usize,
) -> std::io::Result<usize>;
fn read_to_timeout_or_pattern(
&mut self,
buf: &mut Vec<u8>,
pattern: &[u8],
) -> std::io::Result<usize>;
#[deprecated]
fn read_to_pattern_or_timeout(
&mut self,
buf: &mut Vec<u8>,
pattern: &[u8],
) -> std::io::Result<usize>;
}
impl<T: std::io::Read + ?Sized> ReadToTimeout for T {
fn read_to_timeout(&mut self, buf: &mut Vec<u8>) -> std::io::Result<usize> {
let old_len = buf.len();
loop {
let mut read_buf = [0];
match self.read_exact(&mut read_buf) {
Ok(_) => {
buf.push(read_buf[0]);
}
Err(e) => {
return match e.kind() {
std::io::ErrorKind::TimedOut => Ok(buf.len() - old_len),
_ => Err(e),
}
}
}
}
}
fn read_to_timeout_or_bytes(
&mut self,
buf: &mut Vec<u8>,
max_byte: usize,
) -> std::io::Result<usize> {
let old_len = buf.len();
loop {
let mut read_buf = [0];
match self.read_exact(&mut read_buf) {
Ok(_) => {
buf.push(read_buf[0]);
if (buf.len() - old_len) == max_byte {
return Ok(buf.len() - old_len);
}
}
Err(e) => {
return match e.kind() {
std::io::ErrorKind::TimedOut => Ok(buf.len() - old_len),
_ => Err(e),
}
}
}
}
}
fn read_to_timeout_or_pattern(
&mut self,
buf: &mut Vec<u8>,
pattern: &[u8],
) -> std::io::Result<usize> {
let old_len = buf.len();
loop {
let mut byte = [0];
match self.read_exact(&mut byte) {
Ok(_) => {
buf.push(byte[0]);
if buf.len() >= pattern.len()
&& &buf[(buf.len() - pattern.len())..] == pattern
{
break Ok(buf.len() - old_len);
}
}
Err(err) => match err.kind() {
std::io::ErrorKind::TimedOut => {
break Ok(buf.len() - old_len);
}
_ => {
break Err(err);
}
},
}
}
}
fn read_to_pattern_or_timeout(
&mut self,
buf: &mut Vec<u8>,
pattern: &[u8],
) -> std::io::Result<usize> {
self.read_to_timeout_or_pattern(buf, pattern)
}
}
#[cfg(test)]
mod test {
use crate::ReadToTimeout;
#[test]
fn read_pattern() {
let mut bytes: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1];
let mut buffer = Vec::new();
assert_eq!(
bytes.read_to_timeout_or_pattern(&mut buffer, &[7, 6]).unwrap(),
8
);
assert_eq!(buffer, &[1, 2, 3, 4, 5, 6, 7, 6]);
assert_eq!(bytes.read_to_timeout_or_bytes(&mut buffer, 4).unwrap(), 4);
assert_eq!(buffer, &[1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2]);
}
}