node/recorder/
replayer.rs

1use std::{
2    error::Error,
3    fs,
4    io::Read,
5    path::{Path, PathBuf},
6};
7
8use super::{RecordedActionWithMeta, RecordedInitialState};
9
10pub struct StateWithInputActionsReader {
11    dir: PathBuf,
12}
13
14impl StateWithInputActionsReader {
15    pub fn new<P: AsRef<Path>>(dir: P) -> Self {
16        Self {
17            dir: dir.as_ref().to_path_buf(),
18        }
19    }
20
21    pub fn initial_state_path(&self) -> PathBuf {
22        super::initial_state_path(&self.dir)
23    }
24
25    pub fn read_initial_state(&self) -> Result<RecordedInitialState<'_>, Box<dyn Error>> {
26        let path = self.initial_state_path();
27        let encoded = fs::read(path)?;
28        Ok(RecordedInitialState::decode(&encoded)?)
29    }
30
31    pub fn read_actions(
32        &self,
33    ) -> impl Iterator<Item = (PathBuf, impl Iterator<Item = RecordedActionWithMeta<'_>>)> {
34        (1..).map_while(move |file_index| {
35            let path = super::actions_path(&self.dir, file_index);
36            let mut file = fs::File::open(&path).ok()?;
37
38            let iter = std::iter::repeat(()).map_while(move |_| {
39                let mut len_bytes = [0; 8];
40                file.read_exact(&mut len_bytes).ok()?;
41                let len = u64::from_be_bytes(len_bytes);
42
43                let mut data = vec![0; len as usize];
44                file.read_exact(&mut data).unwrap();
45                Some(RecordedActionWithMeta::decode(&data).unwrap())
46            });
47            Some((path, iter))
48        })
49    }
50}