use std::io::{Read, Seek};
use crate::data::control::Control;
pub struct Iter<'a, R: Read + Seek> {
reader: &'a mut R,
reached_stop: bool,
}
impl<'a, R: Read + Seek> Iter<'a, R> {
pub fn new(reader: &'a mut R) -> Iter<'a, R> {
Iter::<'a, R> {
reader,
reached_stop: false,
}
}
}
impl<'a, R: Read + Seek> Iterator for Iter<'a, R> {
type Item = Control;
fn next(&mut self) -> Option<Self::Item> {
if self.reached_stop {
None
} else {
Control::read(self.reader).ok().map(|control| {
if control.command.is_stop() {
self.reached_stop = true;
}
control
})
}
}
}
#[cfg(test)]
mod test {
use std::io::Cursor;
use proptest::prop_assert_eq;
use test_strategy::proptest;
use super::*;
use crate::data::control::Control;
use crate::data::control::tests::generate_valid_control_sequence;
#[proptest]
fn test_control_iterator(
#[strategy(generate_valid_control_sequence(500))] input: Vec<Control>,
) {
let expected = input.clone();
let buf = input
.iter()
.map(|control: &Control| -> Vec<u8> {
let mut buf = Cursor::new(vec![]);
control.write(&mut buf).unwrap();
buf.into_inner()
})
.fold(vec![], |mut acc, mut buf| {
acc.append(&mut buf);
acc
});
let mut cursor = Cursor::new(buf);
let out: Vec<Control> = Iter::new(&mut cursor).collect();
prop_assert_eq!(out, expected);
}
}