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
use super::error::{ValidationError, ValidationErrors};
use super::modifier::Modifier;
use super::rule::Rule;
use serde::Deserialize;
use std::collections::HashMap;
use std::sync::Mutex;
pub struct Validator<T> {
item: T,
rules: Vec<Rule<T>>,
modifiers: Vec<Modifier<T>>,
errors: Mutex<HashMap<String, ValidationError>>,
}
impl<T> Validator<T>
where
T: Clone + for<'de> Deserialize<'de>,
{
pub fn new(item: T) -> Validator<T> {
Validator {
item,
rules: vec![],
modifiers: vec![],
errors: Mutex::new(HashMap::<String, ValidationError>::new()),
}
}
pub fn add_validation(mut self, rule: Rule<T>) -> Self {
self.rules.push(rule);
self
}
pub fn add_modifier(mut self, modifier: Modifier<T>) -> Self {
self.modifiers.push(modifier);
self
}
pub fn contains_rule(&self, key: &str) -> bool {
match self.rules.iter().position(|r| &r.field == key) {
Some(_) => true,
_ => false,
}
}
pub fn contains_modifier(&self, key: &str) -> bool {
match self.modifiers.iter().position(|r| &r.field == key) {
Some(_) => true,
_ => false,
}
}
fn get_error(&self, key: &str) -> ValidationError {
if self.errors.lock().unwrap().contains_key(key) {
if let Some(e) = self.errors.lock().unwrap().remove(key) {
return e;
}
}
ValidationError::new()
}
fn set_error(&self, key: &str, error: ValidationError) {
self.errors.lock().unwrap().insert(key.to_string(), error);
}
fn has_errors(&self) -> bool {
!self.errors.lock().unwrap().is_empty()
}
fn pack_errors(&mut self) -> ValidationErrors {
let mut errors = ValidationErrors::new();
let inner_errors = self.errors.lock().unwrap();
for (_key, error) in inner_errors.iter() {
errors.add(error.clone());
}
errors
}
pub fn run(mut self) -> Result<T, ValidationErrors> {
for modifier in &self.modifiers {
modifier.handle(&mut self.item);
}
for rule in &self.rules {
let mut error = self.get_error(&rule.field);
&rule.handle(&self.item, &mut error);
if error.has_errors() {
self.set_error(&rule.field, error.clone());
}
}
if self.has_errors() {
Err(self.pack_errors())
} else {
Ok(self.item)
}
}
}