sz_orm_core/validation/
mod.rs1pub mod rules;
7
8#[cfg(feature = "validate-on-write")]
9pub mod model_integration;
10
11#[cfg(test)]
12mod derive_tests;
13
14#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
16pub enum ValidationError {
17 #[error("field `{field}` is required but empty")]
19 Required { field: String },
20 #[error("field `{field}` length {actual} not in [{min}, {max}]")]
22 Length {
23 field: String,
24 min: usize,
25 max: usize,
26 actual: usize,
27 },
28 #[error("field `{field}` value {actual} not in [{min}, {max}]")]
30 Range {
31 field: String,
32 min: String,
33 max: String,
34 actual: String,
35 },
36 #[error("field `{field}` value `{value}` is not a valid email")]
38 Email { field: String, value: String },
39 #[error("field `{field}` value `{value}` does not match pattern `{pattern}`")]
41 Regex {
42 field: String,
43 pattern: String,
44 value: String,
45 },
46 #[error("field `{field}` does not contain `{substring}`")]
48 Contains { field: String, substring: String },
49 #[error("field `{field}` contains forbidden `{substring}`")]
51 DoesNotContain { field: String, substring: String },
52 #[error("field `{field}` custom validation failed: {reason}")]
54 Custom { field: String, reason: String },
55 #[error("validation failed with {count} error(s)")]
57 Aggregate {
58 errors: Vec<ValidationError>,
59 count: usize,
60 },
61}
62
63pub trait Validate {
65 fn validate(&self) -> Result<(), ValidationError>;
67}
68
69pub fn aggregate(results: Vec<Result<(), ValidationError>>) -> Result<(), ValidationError> {
71 let errors: Vec<ValidationError> = results.into_iter().filter_map(|r| r.err()).collect();
72 match errors.len() {
73 0 => Ok(()),
74 1 => Err(errors.into_iter().next().unwrap()),
75 n => Err(ValidationError::Aggregate { errors, count: n }),
76 }
77}