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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use libimagstore::storeid::StoreIdIterator;
use libimagstore::store::Store;
use libimagstore::store::FileLockEntry;
use toml_query::read::TomlValueReadTypeExt;
use error::Result;
use error::CategoryError as CE;
use error::CategoryErrorKind as CEK;
use store::CATEGORY_REGISTER_NAME_FIELD_PATH;
use entry::EntryCategory;
use error::ResultExt;
pub struct CategoryNameIter<'a>(&'a Store, StoreIdIterator);
impl<'a> CategoryNameIter<'a> {
pub(crate) fn new(store: &'a Store, sidit: StoreIdIterator) -> CategoryNameIter<'a> {
CategoryNameIter(store, sidit)
}
}
impl<'a> Iterator for CategoryNameIter<'a> {
type Item = Result<String>;
fn next(&mut self) -> Option<Self::Item> {
let query = CATEGORY_REGISTER_NAME_FIELD_PATH;
while let Some(sid) = self.1.next() {
match sid {
Err(e) => return Some(Err(e).map_err(CE::from)),
Ok(sid) => {
if sid.is_in_collection(&["category"]) {
let func = |store: &Store| {
store
.get(sid)?
.ok_or_else(|| CE::from_kind(CEK::StoreReadError))?
.get_header()
.read_string(query)
.chain_err(|| CEK::HeaderReadError)?
.ok_or_else(|| CE::from_kind(CEK::StoreReadError))
};
return Some(func(&self.0))
}
},
}
}
None
}
}
pub struct CategoryEntryIterator<'a>(&'a Store, StoreIdIterator, String);
impl<'a> CategoryEntryIterator<'a> {
pub(crate) fn new(store: &'a Store, sit: StoreIdIterator, name: String) -> Self {
CategoryEntryIterator(store, sit, name)
}
}
impl<'a> Iterator for CategoryEntryIterator<'a> {
type Item = Result<FileLockEntry<'a>>;
fn next(&mut self) -> Option<Self::Item> {
while let Some(next) = self.1.next() {
match next {
Err(e) => return Some(Err(e).map_err(CE::from)),
Ok(next) => {
let getter = |next| -> Result<(String, FileLockEntry<'a>)> {
let entry = self.0
.get(next)?
.ok_or_else(|| CE::from_kind(CEK::StoreReadError))?;
Ok((entry.get_category()?, entry))
};
match getter(next) {
Err(e) => return Some(Err(e)),
Ok((c, e)) => {
if c == self.2 {
return Some(Ok(e))
}
}
}
}
}
}
None
}
}