Skip to content

Commit

Permalink
Offload error handling to user provided deserializer
Browse files Browse the repository at this point in the history
  • Loading branch information
JayKickliter committed Nov 2, 2023
1 parent d73f7ba commit 729d6eb
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 21 deletions.
19 changes: 9 additions & 10 deletions src/disktree/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ pub trait Reader<R> {
/// This can be the serialized type or a result, depending on
/// fallability.
type T;
fn read(&self, rdr: &mut R) -> Self::T;
fn read(&self, rdr: Result<(Cell, &mut R)>) -> Self::T;
}

impl<R, T, F> Reader<R> for F
where
R: Read,
F: Fn(&mut R) -> T,
F: Fn(Result<(Cell, &mut R)>) -> T,
{
type T = T;
fn read(&self, rdr: &mut R) -> T {
fn read(&self, rdr: Result<(Cell, &mut R)>) -> T {
self(rdr)
}
}
Expand Down Expand Up @@ -123,7 +123,7 @@ where
R: Read + Seek,
F: Reader<R>,
{
type Item = Result<(Cell, F::T)>;
type Item = <F as Reader<R>>::T;

fn next(&mut self) -> Option<Self::Item> {
while self.curr.is_none() {
Expand Down Expand Up @@ -163,15 +163,14 @@ where
if let Err(e) = self.seek_to(dptr) {
self.stack.clear();
self.curr = None;
return Some(Err(e));
return Some(self.f.read(Err(e)));
}
let ret: Self::Item = Ok((
return Some(self.f.read(Ok((
*self.cell_stack.cell().expect("corrupted cell-stack"),
self.f.read(self.rdr),
));
return Some(ret);
self.rdr,
))));
}
Err(e) => return Some(Err(e)),
Err(e) => return Some(self.f.read(Err(e))),
};
}
None
Expand Down
33 changes: 26 additions & 7 deletions src/disktree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ mod tests {
use super::*;
use byteorder::{LittleEndian as LE, ReadBytesExt};
use serde::{Deserialize, Serialize};
use std::convert::TryFrom;

#[test]
fn test_roundtrip_monaco() {
Expand Down Expand Up @@ -97,13 +96,33 @@ mod tests {
assert_eq!(*tree_val, disk_val);
}

let reader = |rdr: &mut std::fs::File| bincode::deserialize_from(rdr);
for item_res in monaco_disktree.iter(reader).unwrap() {
// Error type for user-defined deserializer.
#[derive(Debug)]
enum RdrErr {
Bincode(bincode::Error),
Disktree(crate::error::Error),
}

// User-defined deserializer.
fn deserialzer(
res: crate::error::Result<(Cell, &mut impl std::io::Read)>,
) -> Result<(Cell, Cell), RdrErr> {
match res {
Ok((cell, rdr)) => match bincode::deserialize_from(rdr) {
Ok(val) => Ok((cell, val)),
Err(e) => Err(RdrErr::Bincode(e)),
},
Err(e) => Err(RdrErr::Disktree(e)),
}
}

// Create the iterator with the user-defined deserialzer.
let iter = monaco_disktree.iter(deserialzer).unwrap();

for item_res in iter {
let (cell, value) = item_res.unwrap();
let value: u64 = value.unwrap();
let val_cell = Cell::try_from(value).unwrap();
println!("{cell:?} → {val_cell:?}");
assert_eq!(cell, val_cell);
println!("{cell:?} → {value:?}");
assert_eq!(cell, value);
}
}
}
5 changes: 1 addition & 4 deletions src/disktree/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,7 @@ impl<R: Read + Seek> DiskTree<R> {
///
/// However, insteading of returning the concrete value, the
/// iterator retuns a reader pre-seeked to the node's value.
pub fn iter<'a, F>(
&'a mut self,
f: F,
) -> Result<impl Iterator<Item = Result<(Cell, F::T)>> + 'a>
pub fn iter<'a, F>(&'a mut self, f: F) -> Result<impl Iterator<Item = <F as Reader<R>>::T> + 'a>
where
F: Reader<R> + 'a,
{
Expand Down

0 comments on commit 729d6eb

Please sign in to comment.