1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use serde_json::{Map, Value};
use super::Reducer;
#[derive(Debug, Error)]
pub enum ReductionError<Err: ::std::error::Error + ::std::fmt::Debug> {
ImplementationError(Err)
}
pub trait Item: Sized {
type Error: ::std::error::Error + ::std::fmt::Debug;
type Record : super::Record;
type Records : IntoIterator<Item=Self::Record>;
type RecordIter : Iterator<Item=Self::Records>;
fn id(&self) -> &str;
fn record_iter(&self) -> Result<Self::RecordIter, Self::Error>;
fn new_record<S: AsRef<str>, R: ::std::io::Read,
I: Iterator<Item=(S, R)>>(&self, iter: I, link_parents: bool)
-> Result<Self::Record, Self::Error>;
}
pub trait ItemReduction: Item {
fn reduce_with_reducer<R: Reducer<State=Map<String, Value>, Item=Self::Record>>(&self, reducer: &mut R) -> Result<Map<String, Value>, ReductionError<Self::Error>> {
let records = self.record_iter()?;
let mut state: Map<String, Value> = Default::default();
state.insert("id".into(), Value::String(self.id().into()));
Ok(records.fold(state, |acc, recs|
recs.into_iter().fold(acc, |acc, rec| reducer.reduce(acc, &rec))))
}
}
impl<T> ItemReduction for T where T: Item {}