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}