validation_collect/
validation_collect.rs

1use error_rail::Validation;
2
3fn validate_positive(n: i32) -> Validation<&'static str, i32> {
4    if n > 0 {
5        Validation::Valid(n)
6    } else {
7        Validation::invalid("must be positive")
8    }
9}
10
11fn validate_even(n: i32) -> Validation<&'static str, i32> {
12    if n % 2 == 0 {
13        Validation::Valid(n)
14    } else {
15        Validation::invalid("must be even")
16    }
17}
18
19fn validate_number(n: i32) -> Validation<&'static str, i32> {
20    let positive = validate_positive(n);
21    let even = validate_even(n);
22
23    match (positive, even) {
24        (Validation::Valid(_), Validation::Valid(_)) => Validation::Valid(n),
25        (Validation::Invalid(mut a), Validation::Invalid(b)) => {
26            a.extend(b);
27            Validation::Invalid(a)
28        }
29        (Validation::Invalid(errors), _) | (_, Validation::Invalid(errors)) => {
30            Validation::Invalid(errors)
31        }
32    }
33}
34
35fn main() {
36    let input = [1, 2, -3, 4];
37
38    let combined: Validation<&'static str, Vec<i32>> =
39        input.into_iter().map(validate_number).collect();
40
41    match combined {
42        Validation::Valid(values) => println!("valid numbers: {:?}", values),
43        Validation::Invalid(errors) => {
44            for err in errors {
45                println!("validation error: {err}");
46            }
47        }
48    }
49}