1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//! Composable validation traits and error types for Rust structs and values.
//!
//! `reliakit-validate` provides a small, focused toolkit for expressing
//! validation rules as types. The core pieces are:
//!
//! - [`Validate`] — a trait that types implement to describe their validity
//! rules.
//! - [`Valid<T>`] — a zero-cost wrapper that carries proof of successful
//! validation in the type system.
//! - [`ValidationError`] — an error type that collects one or more
//! [`Violation`]s, useful for validating multiple fields at once and
//! returning all failures together.
//!
//! # Examples
//!
//! ## Single-field validation
//!
//! ```
//! use reliakit_validate::{Validate, Valid, ValidationError};
//!
//! struct Username(String);
//!
//! impl Validate for Username {
//! type Error = ValidationError;
//!
//! fn validate(&self) -> Result<(), Self::Error> {
//! if self.0.is_empty() {
//! return Err(ValidationError::new("username must not be empty"));
//! }
//! if self.0.len() > 32 {
//! return Err(ValidationError::new("username must not exceed 32 characters"));
//! }
//! Ok(())
//! }
//! }
//!
//! let user = Valid::new(Username("alice".into())).unwrap();
//! assert_eq!(user.0, "alice");
//! ```
//!
//! ## Multi-field struct validation
//!
//! ```
//! use reliakit_validate::{Validate, ValidationError, Violation};
//!
//! struct CreateUser {
//! name: String,
//! age: u8,
//! }
//!
//! impl Validate for CreateUser {
//! type Error = ValidationError;
//!
//! fn validate(&self) -> Result<(), Self::Error> {
//! let mut errors = ValidationError::empty();
//!
//! if self.name.is_empty() {
//! errors.push(Violation::with_field("name", "must not be empty"));
//! }
//! if self.age < 18 {
//! errors.push(Violation::with_field("age", "must be at least 18"));
//! }
//!
//! if errors.is_empty() { Ok(()) } else { Err(errors) }
//! }
//! }
//!
//! let result = CreateUser { name: String::new(), age: 15 }.validate();
//! assert!(result.is_err());
//! assert_eq!(result.unwrap_err().len(), 2);
//! ```
extern crate alloc;
pub use ;
pub use Valid;
/// A type that can validate itself.
///
/// Implement this trait to express the validity rules of a type. Use
/// [`Valid<T>`] to wrap validated values and carry the proof in the type
/// system.
///
/// # Example
///
/// ```
/// use reliakit_validate::{Validate, ValidationError};
///
/// struct Score(u8);
///
/// impl Validate for Score {
/// type Error = ValidationError;
///
/// fn validate(&self) -> Result<(), Self::Error> {
/// if self.0 > 100 {
/// return Err(ValidationError::new("score must not exceed 100"));
/// }
/// Ok(())
/// }
/// }
///
/// assert!(Score(100).validate().is_ok());
/// assert!(Score(101).validate().is_err());
/// ```