1use std::{
2 fmt::{Debug, Display},
3 rc::Rc,
4};
5
6pub struct ValidationError<Key> {
8 pub key: Key,
10 pub type_id: &'static str,
12 message: Rc<dyn Fn(&Key) -> String>,
14}
15
16impl<Key> PartialEq for ValidationError<Key>
17where
18 Key: PartialEq,
19{
20 fn eq(&self, other: &Self) -> bool {
21 self.key == other.key
22 && self.type_id == other.type_id
23 && self.get_message() == other.get_message()
24 }
25}
26
27impl<Key> Clone for ValidationError<Key>
28where
29 Key: Clone,
30{
31 fn clone(&self) -> Self {
32 Self {
33 key: self.key.clone(),
34 type_id: self.type_id,
35 message: self.message.clone(),
36 }
37 }
38}
39
40impl<Key> ValidationError<Key> {
41 pub fn new(key: Key, type_id: &'static str) -> Self {
45 Self {
46 key,
47 message: Rc::new(|_| "Validation error".to_string()),
48 type_id,
49 }
50 }
51
52 pub fn message<S: Into<String>>(mut self, message: S) -> Self {
54 let message_string = message.into();
55 self.message = Rc::new(move |_| message_string.clone());
56 self
57 }
58
59 pub fn with_message<F: Fn(&Key) -> String + 'static>(mut self, message_fn: F) -> Self {
78 self.message = Rc::new(message_fn);
79 self
80 }
81
82 fn get_message(&self) -> String {
84 (self.message)(&self.key)
85 }
86}
87
88impl<Key> Display for ValidationError<Key> {
89 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90 write!(f, "{}", self.get_message())
91 }
92}
93
94impl<Key> Debug for ValidationError<Key>
95where
96 Key: Debug,
97{
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 write!(
100 f,
101 "ValidationError{{ key: {0:?}, type_id: {1}, message: {2} }}",
102 self.key,
103 self.type_id,
104 self.get_message()
105 )
106 }
107}
108
109impl<Key> std::error::Error for ValidationError<Key> where Key: Debug {}
110
111#[derive(Debug, Clone)]
114pub struct ValidationErrors<Key> {
115 pub errors: Vec<ValidationError<Key>>,
116}
117
118impl<Key> PartialEq for ValidationErrors<Key>
119where
120 Key: PartialEq,
121{
122 fn eq(&self, other: &Self) -> bool {
123 self.errors.eq(&other.errors)
124 }
125}
126
127impl<Key> ValidationErrors<Key>
128where
129 Key: PartialEq + Clone,
130{
131 pub fn new(errors: Vec<ValidationError<Key>>) -> Self {
133 Self { errors }
134 }
135
136 pub fn get(&self, key: &Key) -> Option<ValidationErrors<Key>> {
139 let errors: Vec<ValidationError<Key>> = self
140 .errors
141 .iter()
142 .filter(|error| &error.key == key)
143 .map(|error| (*error).clone())
144 .collect();
145
146 if !errors.is_empty() {
147 Some(ValidationErrors::new(errors))
148 } else {
149 None
150 }
151 }
152
153 pub fn is_empty(&self) -> bool {
155 self.errors.is_empty()
156 }
157
158 pub fn extend(&mut self, errors: ValidationErrors<Key>) {
161 self.errors.extend(errors.errors)
162 }
163
164 pub fn len(&self) -> usize {
166 self.errors.len()
167 }
168}
169
170impl<Key> Default for ValidationErrors<Key> {
171 fn default() -> Self {
172 Self { errors: Vec::new() }
173 }
174}
175
176impl<Key> Display for ValidationErrors<Key> {
177 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
178 let errors: Vec<String> = self.errors.iter().map(|e| format!("{}", e)).collect();
179 write!(f, "{}", errors.join(", "))
180 }
181}
182
183impl<Key> std::error::Error for ValidationErrors<Key> where Key: std::fmt::Debug {}
184
185impl<Key> From<ValidationError<Key>> for ValidationErrors<Key>
186where
187 Key: Clone + PartialEq,
188{
189 fn from(err: ValidationError<Key>) -> Self {
190 ValidationErrors::new(vec![err])
191 }
192}