rusthound_ce/storage/
iter.rs1use std::error::Error;
2use std::fs::File;
3use std::io::{BufReader, Read};
4use std::marker::PhantomData;
5
6pub type DiskStorageReader<T> = BincodeIterator<T, BufReader<File>>;
7
8pub struct BincodeIterator<T, R: Read> {
10 reader: R,
11 _phantom: PhantomData<T>,
12}
13
14impl<T> BincodeIterator<T, BufReader<File>>
15where
16 T: bincode::Decode<()>,
17{
18 pub fn from_path(file_path: impl AsRef<std::path::Path>) -> std::io::Result<Self> {
20 let file = File::open(file_path)?;
21 let reader = BufReader::new(file);
22 Ok(Self {
23 reader,
24 _phantom: PhantomData,
25 })
26 }
27
28 pub fn from_file(file: std::fs::File) -> Self {
29 Self {
30 reader: BufReader::new(file),
31 _phantom: PhantomData,
32 }
33 }
34}
35
36impl<T, R: Read> BincodeIterator<T, R>
37where
38 T: bincode::Decode<()>,
39{
40 pub fn new(reader: R) -> Self {
42 Self {
43 reader,
44 _phantom: PhantomData,
45 }
46 }
47}
48
49impl<T, R: Read> Iterator for BincodeIterator<T, R>
50where
51 T: bincode::Decode<()>,
52{
53 type Item = Result<T, Box<dyn Error>>;
54
55 fn next(&mut self) -> Option<Self::Item> {
56 let mut len_bytes = [0u8; 4];
58 match self.reader.read_exact(&mut len_bytes) {
59 Ok(()) => {}
60 Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => {
61 return None;
63 }
64 Err(e) => return Some(Err(e.into())),
65 }
66
67 let len = u32::from_le_bytes(len_bytes) as usize;
68
69 let mut data = vec![0u8; len];
80 if let Err(e) = self.reader.read_exact(&mut data) {
81 return Some(Err(format!("Failed to read {len} bytes: {e}").into()));
82 }
83
84 match bincode::decode_from_slice::<T, _>(&data, bincode::config::standard()) {
86 Ok((item, _)) => Some(Ok(item)),
87 Err(e) => Some(Err(format!("Failed to decode item: {e:?}").into())),
88 }
89 }
90}