some extra iterator utilities

This commit is contained in:
Chris West (Faux) 2017-10-15 15:44:24 +01:00
parent db3be1e3d2
commit 370a764967
4 changed files with 88 additions and 0 deletions

View File

@ -22,4 +22,5 @@ lazy_static = "0.2.9"
libc = "0.2.32"
[dev-dependencies]
boolinator = "2.4.0"
itertools = "0.7.1"

18
examples/epochs.rs Normal file
View File

@ -0,0 +1,18 @@
extern crate apt_pkg_native;
extern crate boolinator;
use apt_pkg_native::Cache;
use boolinator::Boolinator;
fn main() {
let mut cache = Cache::get_singleton();
for item in cache.iter().filter_map(|f| {
f.versions()
.any(|version| version.version().contains(':'))
.as_some_from(|| f.name())
})
{
println!("{}", item);
}
}

View File

@ -81,6 +81,40 @@ where
CMap { it: self, f }
}
pub fn filter_map<F, B>(self, f: F) -> CFilterMap<R, F>
where
F: FnMut(&R::View) -> Option<B>,
{
CFilterMap { it: self, f }
}
pub fn any<F>(mut self, mut f: F) -> bool
where
F: FnMut(&R::View) -> bool,
{
while let Some(view) = self.next() {
if (f)(&view) {
return true;
}
}
false
}
pub fn all<F>(mut self, mut f: F) -> bool
where
F: FnMut(&R::View) -> bool,
{
while let Some(view) = self.next() {
if !(f)(&view) {
return false;
}
}
true
}
pub fn count(mut self) -> usize {
// Not sure this is actually better than self.map(|_| ()).count()
@ -118,3 +152,33 @@ where
}
}
}
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct CFilterMap<R, F>
where
R: RawIterator,
{
it: CIterator<R>,
f: F,
}
impl<B, R, F> Iterator for CFilterMap<R, F>
where
R: RawIterator,
F: FnMut(&R::View) -> Option<B>,
{
type Item = B;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.it.next() {
Some(ref x) => {
if let Some(y) = (self.f)(x) {
return Some(y);
}
}
None => return None,
}
}
}
}

View File

@ -72,6 +72,11 @@ mod tests {
.next()
.is_none()
);
}
#[test]
fn find_by_filter_map() {
let mut cache = Cache::get_singleton();
}