catlog/
validate.rs

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