pub trait AtLeast<T, E, Factory>: Iterator<Item = Result<T, E>> + Sized{
// Provided method
fn at_least(
self,
min_count: usize,
factory: Factory,
) -> AtLeastIter<Self, T, E, Factory> { ... }
}
Provided Methods§
sourcefn at_least(
self,
min_count: usize,
factory: Factory,
) -> AtLeastIter<Self, T, E, Factory>
fn at_least( self, min_count: usize, factory: Factory, ) -> AtLeastIter<Self, T, E, Factory>
Fails a validation iterator if it does not contain n
or more elements.
at_least(n, factory)
yields Ok(element)
values until the iteration ends. If the
number of values in the iteration is less than n
, a new element is
added to the end of the iteration with the value returned from calling factory
on the length of the iterator.
The at_least
adapter cannot handle short-circuiting of iterators, so
iterations such as (0..10).validate().at_least(100).take(5)
will not
fail.
Elements already wrapped in Result::Err
will not be
counted towards reaching the n
elements lower bound.
The length provided to factory
includes elements wrapped in Result::Err
.
§Examples
Basic usage:
struct NotEnough(usize);
let mut iter = a.iter().map(|v| Ok(v)).at_least(4, |i| NotEnough(i));
assert_eq!(iter.next(), Some(Ok(&1)));
assert_eq!(iter.next(), Some(Ok(&2)));
assert_eq!(iter.next(), Some(Ok(&3)));
assert_eq!(iter.next(), Some(Err(NotEnough(3))));
assert_eq!(iter.next(), None);
at_least
could be used to ensure that a vector created from an iterator
has a value in some index:
use validiter::AtLeast;
let iter = 0..=2; // iteration is too short, no 4th element!
let collection: Result<Vec<_>, _> = iter
.map(|v| Ok(v))
.at_least(4, |_| Err::<i32, ()>(()))
.collect();
match collection {
Ok(vec) => {
let val = vec[3]; // doesn't crash, because the collection failed.
}
Err(_) => {} // handle error
};
at_least
will not account for errors already in the iteration:
let mut iter = [Ok(0), Err(404)]
.into_iter()
.at_least(2, |_| 505);
assert_eq!(iter.next(), Some(Ok(0)));
assert_eq!(iter.next(), Some(Err(404)));
assert_eq!(iter.next(), Some(Err(505)));
Examples found in repository?
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
fn main() {
// In this example we will use the 'cast_errs' method to
// create a 'Vec<Vec<f64>>' collection, while ensuring
// the mathematical validity if this collection as a numerical
// matrix. To exercise the 'ensure' adapter, we'll force all
// elements to be non-negative as well
// Here we define the errors we expect to encounter in
// the parsing process:
#[derive(Debug)]
enum MatParseErr {
NotAFloat(usize, usize, ParseFloatError),
NoColumns(usize),
Negative(usize, usize, f64),
NoRows,
JaggedArray(usize, Vec<f64>, usize, usize),
}
// this is a CSV format str, with 2 rows and 2 columns
let csv = "1.2, 3.0
4.2, 0.5";
// we'll use iterator methods on the CSV to build an actual matrix over f64
let mat = csv
.lines()
.enumerate()
.map(|(i, line)| {
line.split(",")
.map(|s| s.trim())
.enumerate()
.map(|(j, s)| {
s.parse::<f64>()
.map_err(|parse_err| MatParseErr::NotAFloat(i, j, parse_err))
})
.ensure(|val| *val >= 0.0, |j, val| MatParseErr::Negative(i, j, val))
.at_least(1, |_| MatParseErr::NoColumns(i))
.collect::<Result<Vec<f64>, MatParseErr>>()
})
.at_least(1, |_| MatParseErr::NoRows)
.const_over(
|vec| vec.len(),
|i, vec, len, expected_len| MatParseErr::JaggedArray(i, vec, len, *expected_len),
)
.collect::<Result<Vec<_>, _>>();
match mat {
Ok(mat) => {
assert_eq!(mat, vec![vec![1.2, 3.0], vec![4.2, 0.5]]);
println!("{mat:?}")
}
Err(mperr) => match mperr {
MatParseErr::NotAFloat(i, j, err) => println!("Got {err} at pos [{i}, {j}]"),
MatParseErr::NoColumns(i) => {
println!("Row {i} is without any data, which would force the matrix to be empty")
}
MatParseErr::Negative(i, j, val) => {
println!("value {val} at pos [{i}, {j}] is negative")
}
MatParseErr::NoRows => println!("There are no rows in the matrix"),
MatParseErr::JaggedArray(i, _vec, len, expected_len) => {
println!("Row {i} has len {len}, when all rows should have length {expected_len}")
}
},
}
}