pub trait LookBack<T, E, A, M, F, Factory>: Iterator<Item = Result<T, E>> + Sized{
// Provided method
fn look_back(
self,
steps: usize,
extractor: M,
test: F,
factory: Factory,
) -> LookBackIter<Self, T, E, A, M, F, Factory> { ... }
}
Provided Methods§
sourcefn look_back(
self,
steps: usize,
extractor: M,
test: F,
factory: Factory,
) -> LookBackIter<Self, T, E, A, M, F, Factory>
fn look_back( self, steps: usize, extractor: M, test: F, factory: Factory, ) -> LookBackIter<Self, T, E, A, M, F, Factory>
Fails an iteration if it does not conform to some cycling of properties.
look_back(steps, extractor, validation, factory)
takes 4
arguments:
n
- ausize
describing a cycle lengthextractor
- a mapping of iterator elements to some extracted value.test
- a test which accepts the value extracted from the nth preceding element, and tests the current element based on this value.- An error factory.
Each iterator element wrapped in Ok(element)
gets processed in
these 2 ways:
- Assuming there was a previous nth element (we’ll call it
p_nth
), the current element is tested forvalidation(element, extractor(p_nth))
. - If the element passed the test, it is wrapped in
Ok(element)
. otherwisefactory
gets called on the index of the error, the failing element, and a reference to the extracted value that failed the element.
§Examples
Basic usage:
let mut iter = (0..=2).chain(2..=4).map(|v| Ok(v)).look_back(
2,
|i| *i,
|prev, i| prev % 2 == i % 2,
|index, val, failed_against| (index, val, *failed_against),
);
assert_eq!(iter.next(), Some(Ok(0)));
assert_eq!(iter.next(), Some(Ok(1)));
assert_eq!(iter.next(), Some(Ok(2))); // evaluated with respect to 0
assert_eq!(iter.next(), Some(Err((3, 2, 1)))); // at index 3, 2 is evaluated with respect to 1
assert_eq!(iter.next(), Some(Ok(3))); // also evaluated with respect to 1
assert_eq!(iter.next(), Some(Ok(4))); // evaluted with respect to 2
look_back
can be used to force a monotonic iteration with relation to some
property, with the most obvious example being the ‘monotonic increasing’ one:
(1..)
.map(|i| Ok((i as f64).log(std::f64::consts::E)))
.look_back(1, |val| *val, |val, prev| val > prev, |_, _, _| ())
.take(10)
.for_each(|f| {
f.expect("log e is not monotonic!");
});
look_back
could be used to force an iteration to cycle through
a sequence of predetermined properties:
let sequence = "abc";
let s = "abfbc";
let mut iter = sequence.chars().chain(s.chars()).map(|c| Ok(c)).look_back(
3,
|c| *c,
|p_nth, c| p_nth == c,
|_, _, _| (),
);
assert_eq!(iter.next(), Some(Ok('a')));
assert_eq!(iter.next(), Some(Ok('b')));
assert_eq!(iter.next(), Some(Ok('c')));
assert_eq!(iter.next(), Some(Ok('a')));
assert_eq!(iter.next(), Some(Ok('b')));
assert_eq!(iter.next(), Some(Err(())));
assert_eq!(iter.next(), Some(Err(())));
assert_eq!(iter.next(), Some(Ok('c')));
Object Safety§
This trait is not object safe.