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?
5fn main() {
6 // In this example we will use the 'cast_errs' method to
7 // create a 'Vec<Vec<f64>>' collection, while ensuring
8 // the mathematical validity if this collection as a numerical
9 // matrix. To exercise the 'ensure' adapter, we'll force all
10 // elements to be non-negative as well
11
12 // Here we define the errors we expect to encounter in
13 // the parsing process:
14 #[derive(Debug)]
15 enum MatParseErr {
16 NotAFloat(usize, usize, ParseFloatError),
17 NoColumns(usize),
18 Negative(usize, usize, f64),
19 NoRows,
20 JaggedArray(usize, Vec<f64>, usize, usize),
21 }
22
23 // this is a CSV format str, with 2 rows and 2 columns
24 let csv = "1.2, 3.0
25 4.2, 0.5";
26
27 // we'll use iterator methods on the CSV to build an actual matrix over f64
28 let mat = csv
29 .lines()
30 .enumerate()
31 .map(|(i, line)| {
32 line.split(",")
33 .map(|s| s.trim())
34 .enumerate()
35 .map(|(j, s)| {
36 s.parse::<f64>()
37 .map_err(|parse_err| MatParseErr::NotAFloat(i, j, parse_err))
38 })
39 .ensure(|val| *val >= 0.0, |j, val| MatParseErr::Negative(i, j, val))
40 .at_least(1, |_| MatParseErr::NoColumns(i))
41 .collect::<Result<Vec<f64>, MatParseErr>>()
42 })
43 .at_least(1, |_| MatParseErr::NoRows)
44 .const_over(
45 |vec| vec.len(),
46 |i, vec, len, expected_len| MatParseErr::JaggedArray(i, vec, len, *expected_len),
47 )
48 .collect::<Result<Vec<_>, _>>();
49
50 match mat {
51 Ok(mat) => {
52 assert_eq!(mat, vec![vec![1.2, 3.0], vec![4.2, 0.5]]);
53 println!("{mat:?}")
54 }
55 Err(mperr) => match mperr {
56 MatParseErr::NotAFloat(i, j, err) => println!("Got {err} at pos [{i}, {j}]"),
57 MatParseErr::NoColumns(i) => {
58 println!("Row {i} is without any data, which would force the matrix to be empty")
59 }
60 MatParseErr::Negative(i, j, val) => {
61 println!("value {val} at pos [{i}, {j}] is negative")
62 }
63 MatParseErr::NoRows => println!("There are no rows in the matrix"),
64 MatParseErr::JaggedArray(i, _vec, len, expected_len) => {
65 println!("Row {i} has len {len}, when all rows should have length {expected_len}")
66 }
67 },
68 }
69}
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.