catlog/
validate.rs

1/*! Objects that can validate themselves.
2
3The design is loosely inspired by the
4[`validator`](https://crates.io/crates/validator) package, but to support the
5use case of compositional validation in a library (rather than an application),
6the validation error type is generic, not string-based.
7 */
8
9use nonempty::NonEmpty;
10
11/** An object that can validate itself.
12
13Such an object is either valid, a state which carries no additional information,
14or is invalid, a state described by a nonempty list of validation errors.
15 */
16pub trait Validate {
17    /** The type of a validation error.
18
19    This type should usually implement [`std::error::Error`], though that is not
20    required.
21    */
22    type ValidationError;
23
24    /// Validates the object.
25    fn validate(&self) -> Result<(), NonEmpty<Self::ValidationError>>;
26}
27
28/** Wrap iterator of validation errors into a `Result`.
29
30It is common to implement [`Validate`] by constructing an iterator over
31validation errors and then calling this convenience function.
32*/
33pub fn wrap_errors<Error>(iter: impl Iterator<Item = Error>) -> Result<(), NonEmpty<Error>> {
34    match NonEmpty::collect(iter) {
35        Some(errors) => Err(errors),
36        None => Ok(()),
37    }
38}
39
40/**  Unwrap `Result` with validation errors into a list of errors.
41 */
42pub fn unwrap_errors<Error>(result: Result<(), NonEmpty<Error>>) -> Vec<Error> {
43    match result {
44        Ok(()) => Vec::new(),
45        Err(errs) => errs.into(),
46    }
47}