fixup borrows on nasty iterators
This commit is contained in:
parent
d4d85c2485
commit
00188891eb
29
src/citer.rs
29
src/citer.rs
@ -1,3 +1,6 @@
|
||||
use std::ops::Deref;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub trait RawIterator {
|
||||
type View;
|
||||
|
||||
@ -26,11 +29,30 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Borrowed<'i, R>
|
||||
where
|
||||
R: 'i + RawIterator,
|
||||
{
|
||||
it: PhantomData<&'i CIterator<R>>,
|
||||
val: R::View,
|
||||
}
|
||||
|
||||
impl<'i, R> Deref for Borrowed<'i, R>
|
||||
where
|
||||
R: RawIterator,
|
||||
{
|
||||
type Target = R::View;
|
||||
|
||||
fn deref(&self) -> &R::View {
|
||||
&self.val
|
||||
}
|
||||
}
|
||||
|
||||
impl<R> CIterator<R>
|
||||
where
|
||||
R: RawIterator,
|
||||
{
|
||||
pub fn next(&mut self) -> Option<R::View> {
|
||||
pub fn next<'i>(&mut self) -> Option<Borrowed<R>> {
|
||||
if self.raw.is_end() {
|
||||
return None;
|
||||
}
|
||||
@ -45,7 +67,10 @@ where
|
||||
if self.raw.is_end() {
|
||||
None
|
||||
} else {
|
||||
Some(self.raw.as_view())
|
||||
Some(Borrowed {
|
||||
it: PhantomData,
|
||||
val: self.raw.as_view(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
27
src/lib.rs
27
src/lib.rs
@ -13,8 +13,7 @@
|
||||
//! a bit more like Rust `Iterator`s, but is crippled by the insanity.
|
||||
//!
|
||||
//! Methods which "find" something will reposition one of these "iterators" at the right place
|
||||
//! in an existing stream of items. Note that currently you don't technically need to call
|
||||
//! `next()` before observing the result of a `find..()`, but hopefully this will be fixed.
|
||||
//! in an existing stream of items.
|
||||
//!
|
||||
//! I recommend using `.map()` to turn an "iterator" into a Rust type as soon as possible.
|
||||
//! The returned map-like thing *is* a Rust `Iterator`, so you can do normal operations on it.
|
||||
@ -25,7 +24,7 @@
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! extern crate apt_pkg_native;
|
||||
//! let cache = apt_pkg_native::Cache::get_singleton();
|
||||
//! let mut cache = apt_pkg_native::Cache::get_singleton();
|
||||
//! let total_packages = cache.iter().map(|_| ()).count();
|
||||
//! ```
|
||||
//!
|
||||
@ -63,20 +62,14 @@ mod tests {
|
||||
panic!("not found!");
|
||||
}
|
||||
|
||||
assert!(cache.find_by_name(
|
||||
"this-package-doesnt-exist-and-if-someone-makes-it-ill-be-really-angry",
|
||||
).next().is_none());
|
||||
assert!(
|
||||
cache
|
||||
.find_by_name(
|
||||
"this-package-doesnt-exist-and-if-someone-makes-it-ill-be-really-angry",
|
||||
)
|
||||
.next()
|
||||
.is_none()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// TODO: this should not even remotely compile
|
||||
#[test]
|
||||
fn demonstrate_insane_iterator_behaviour() {
|
||||
let mut cache = Cache::get_singleton();
|
||||
let mut it = cache.iter();
|
||||
let first = it.next().unwrap();
|
||||
let second = it.next().unwrap();
|
||||
assert_eq!(first.arch(), second.arch());
|
||||
assert_eq!(first.name(), second.name());
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ pub type PCache = *mut c_void;
|
||||
pub type PPkgIterator = *mut c_void;
|
||||
pub type PVerIterator = *mut c_void;
|
||||
|
||||
#[link(name = "apt-pkg-c", kind = "static")]
|
||||
#[link(name = "apt-pkg")]
|
||||
extern "C" {
|
||||
/// Must be called exactly once, before anything else?
|
||||
|
Loading…
Reference in New Issue
Block a user