pub trait ConstOver<T, E, A, M, Factory>: Iterator<Item = Result<T, E>> + Sized{
// Provided method
fn const_over(
self,
extractor: M,
factory: Factory,
) -> ConstOverIter<Self, T, E, A, M, Factory> { ... }
}
Provided Methods§
Sourcefn const_over(
self,
extractor: M,
factory: Factory,
) -> ConstOverIter<Self, T, E, A, M, Factory>
fn const_over( self, extractor: M, factory: Factory, ) -> ConstOverIter<Self, T, E, A, M, Factory>
Fails an iteration if extractor
does not give the same result
for all elements.
const_over(extractor, factory)
takes a Fn
argument that computes
some value for each element in iteration. If for some element
this results in a value which is not equal to value computed
from the first element, factory
is called on the current iteration index,
the element, the value extracted from this element, and the first value
(which the extraction failed to equal). Otherwise, the element
is wrapped in Ok(element)
. The first valid element is always wrapped
in Ok
.
§Examples
Basic usage:
use validiter::ConstOver;
let somecase = "ABc";
let mut iter = somecase.chars().map(|c| Ok(c)).const_over(
|c| c.is_uppercase(),
|index, char, case, expected_case| {
(index, char, case, *expected_case == 'A'.is_uppercase())
},
);
assert_eq!(iter.next(), Some(Ok('A')));
assert_eq!(iter.next(), Some(Ok('B')));
assert_eq!(
iter.next(),
Some(Err((2, 'c', false, true)))
);
const_over
ignores errors:
use validiter::ConstOver;
use validiter::Ensure;
#[derive(Debug, PartialEq)]
enum IterErr {
IsA,
CaseChanged,
}
let uppercase = "Abc";
let mut iter = uppercase
.chars()
.map(|v| Ok(v))
.ensure(|c| *c != 'A', |_, _| IterErr::IsA)
.const_over(|c| c.is_uppercase(), |_, _, _, _| IterErr::CaseChanged);
assert_eq!(
iter.next(),
Some(Err(IterErr::IsA))
);
assert_eq!(iter.next(), Some(Ok('b')));
assert_eq!(iter.next(), Some(Ok('c')));
Examples found in repository?
examples/numeric_csv_parsing.rs (lines 44-47)
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.