use std::io::{Read, Seek};
use std::marker::PhantomData;
use crate::data::control::mode::Mode;
use crate::data::control::Control;
pub struct Iter<'a, R: Read + Seek, M: Mode> {
reader: &'a mut R,
reached_stop: bool,
mode: PhantomData<M>,
}
impl<'a, R: Read + Seek, M: Mode> Iter<'a, R, M> {
pub fn new(reader: &'a mut R) -> Iter<'a, R, M> {
Iter::<'a, R, M> {
reader,
reached_stop: false,
mode: PhantomData,
}
}
}
impl<'a, R: Read + Seek, M: Mode> Iterator for Iter<'a, R, M> {
type Item = Control;
fn next(&mut self) -> Option<Self::Item> {
if self.reached_stop {
None
} else {
Control::read::<M>(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::mode::Reference;
use crate::data::control::tests::generate_valid_control_sequence;
use crate::data::control::Control;
#[proptest]
fn test_control_iterator(
#[strategy(generate_valid_control_sequence::<Reference>(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::<Reference>(&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::<_, Reference>::new(&mut cursor).collect();
prop_assert_eq!(out, expected);
}
}