1use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9pub trait Serializer {
31 type Input;
33 type Output;
35
36 fn serialize(&self, input: &Self::Input) -> Result<Self::Output, SerializerError>;
38 fn deserialize(&self, output: &Self::Output) -> Result<Self::Input, SerializerError>;
40}
41
42#[non_exhaustive]
44#[derive(Debug, Clone, PartialEq, Eq)]
45pub enum ValidatorError {
46 UniqueViolation {
48 field_name: String,
50 value: String,
52 message: String,
54 },
55 UniqueTogetherViolation {
57 field_names: Vec<String>,
59 values: HashMap<String, String>,
61 message: String,
63 },
64 RequiredField {
66 field_name: String,
68 message: String,
70 },
71 FieldValidation {
73 field_name: String,
75 value: String,
77 constraint: String,
79 message: String,
81 },
82 DatabaseError {
84 message: String,
86 source: Option<String>,
88 },
89 Custom {
91 message: String,
93 },
94}
95
96impl std::fmt::Display for ValidatorError {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 match self {
99 ValidatorError::UniqueViolation {
100 field_name,
101 value,
102 message,
103 } => write!(
104 f,
105 "Unique violation on field '{}' with value '{}': {}",
106 field_name, value, message
107 ),
108 ValidatorError::UniqueTogetherViolation {
109 field_names,
110 values,
111 message,
112 } => {
113 let fields_str = format!("[{}]", field_names.join(", "));
115 let mut sorted_values: Vec<_> = values.iter().collect();
118 sorted_values.sort_by_key(|(k, _)| *k);
119 let values_str = sorted_values
120 .into_iter()
121 .map(|(k, v)| format!("{}={}", k, v))
122 .collect::<Vec<_>>()
123 .join(", ");
124 write!(
125 f,
126 "Unique together violation on fields {} with values ({}): {}",
127 fields_str, values_str, message
128 )
129 }
130 ValidatorError::RequiredField {
131 field_name,
132 message,
133 } => write!(f, "Required field '{}': {}", field_name, message),
134 ValidatorError::FieldValidation {
135 field_name,
136 value,
137 constraint,
138 message,
139 } => write!(
140 f,
141 "Field '{}' with value '{}' failed constraint '{}': {}",
142 field_name, value, constraint, message
143 ),
144 ValidatorError::DatabaseError { message, source } => {
145 if let Some(src) = source {
146 write!(f, "Database error: {} (source: {})", message, src)
147 } else {
148 write!(f, "Database error: {}", message)
149 }
150 }
151 ValidatorError::Custom { message } => write!(f, "Validation error: {}", message),
152 }
153 }
154}
155
156impl std::error::Error for ValidatorError {}
157
158impl ValidatorError {
159 pub fn message(&self) -> &str {
161 match self {
162 ValidatorError::UniqueViolation { message, .. } => message,
163 ValidatorError::UniqueTogetherViolation { message, .. } => message,
164 ValidatorError::RequiredField { message, .. } => message,
165 ValidatorError::FieldValidation { message, .. } => message,
166 ValidatorError::DatabaseError { message, .. } => message,
167 ValidatorError::Custom { message } => message,
168 }
169 }
170
171 pub fn field_names(&self) -> Vec<&str> {
173 match self {
174 ValidatorError::UniqueViolation { field_name, .. } => vec![field_name.as_str()],
175 ValidatorError::UniqueTogetherViolation { field_names, .. } => {
176 field_names.iter().map(|s| s.as_str()).collect()
177 }
178 ValidatorError::RequiredField { field_name, .. } => vec![field_name.as_str()],
179 ValidatorError::FieldValidation { field_name, .. } => vec![field_name.as_str()],
180 ValidatorError::DatabaseError { .. } => vec![],
181 ValidatorError::Custom { .. } => vec![],
182 }
183 }
184
185 pub fn is_uniqueness_violation(&self) -> bool {
187 matches!(
188 self,
189 ValidatorError::UniqueViolation { .. } | ValidatorError::UniqueTogetherViolation { .. }
190 )
191 }
192
193 pub fn is_database_error(&self) -> bool {
195 matches!(self, ValidatorError::DatabaseError { .. })
196 }
197}
198
199#[non_exhaustive]
201#[derive(Debug, Clone, PartialEq, Eq)]
202pub enum SerializerError {
203 Validation(ValidatorError),
205 Serde {
207 message: String,
209 },
210 Other {
212 message: String,
214 },
215}
216
217impl std::fmt::Display for SerializerError {
218 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
219 match self {
220 SerializerError::Validation(e) => write!(f, "{}", e),
221 SerializerError::Serde { message } => write!(f, "Serde error: {}", message),
222 SerializerError::Other { message } => write!(f, "Serialization error: {}", message),
223 }
224 }
225}
226
227impl std::error::Error for SerializerError {
228 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
229 match self {
230 SerializerError::Validation(e) => Some(e),
231 _ => None,
232 }
233 }
234}
235
236impl From<ValidatorError> for SerializerError {
237 fn from(err: ValidatorError) -> Self {
238 SerializerError::Validation(err)
239 }
240}
241
242impl SerializerError {
243 pub fn new(message: String) -> Self {
245 SerializerError::Other { message }
246 }
247
248 pub fn validation(error: ValidatorError) -> Self {
250 SerializerError::Validation(error)
251 }
252
253 pub fn unique_violation(field_name: String, value: String, message: String) -> Self {
255 SerializerError::Validation(ValidatorError::UniqueViolation {
256 field_name,
257 value,
258 message,
259 })
260 }
261
262 pub fn unique_together_violation(
264 field_names: Vec<String>,
265 values: HashMap<String, String>,
266 message: String,
267 ) -> Self {
268 SerializerError::Validation(ValidatorError::UniqueTogetherViolation {
269 field_names,
270 values,
271 message,
272 })
273 }
274
275 pub fn required_field(field_name: String, message: String) -> Self {
277 SerializerError::Validation(ValidatorError::RequiredField {
278 field_name,
279 message,
280 })
281 }
282
283 pub fn field_validation(
285 field_name: String,
286 value: String,
287 constraint: String,
288 message: String,
289 ) -> Self {
290 SerializerError::Validation(ValidatorError::FieldValidation {
291 field_name,
292 value,
293 constraint,
294 message,
295 })
296 }
297
298 pub fn database_error(message: String, source: Option<String>) -> Self {
300 SerializerError::Validation(ValidatorError::DatabaseError { message, source })
301 }
302
303 pub fn is_validation_error(&self) -> bool {
305 matches!(self, SerializerError::Validation(_))
306 }
307
308 pub fn message(&self) -> String {
310 match self {
311 SerializerError::Validation(e) => e.message().to_string(),
312 SerializerError::Serde { message } => message.clone(),
313 SerializerError::Other { message } => message.clone(),
314 }
315 }
316
317 pub fn as_validator_error(&self) -> Option<&ValidatorError> {
319 match self {
320 SerializerError::Validation(e) => Some(e),
321 _ => None,
322 }
323 }
324}
325
326#[derive(Debug, Clone)]
350pub struct JsonSerializer<T> {
351 _phantom: std::marker::PhantomData<T>,
352}
353
354impl<T> JsonSerializer<T> {
355 pub fn new() -> Self {
357 Self {
358 _phantom: std::marker::PhantomData,
359 }
360 }
361}
362
363impl<T> Default for JsonSerializer<T> {
364 fn default() -> Self {
365 Self::new()
366 }
367}
368
369impl<T> Serializer for JsonSerializer<T>
370where
371 T: Serialize + for<'de> Deserialize<'de>,
372{
373 type Input = T;
374 type Output = String;
375
376 fn serialize(&self, input: &Self::Input) -> Result<Self::Output, SerializerError> {
377 serde_json::to_string(input).map_err(|e| SerializerError::Serde {
378 message: format!("Serialization error: {}", e),
379 })
380 }
381
382 fn deserialize(&self, output: &Self::Output) -> Result<Self::Input, SerializerError> {
383 serde_json::from_str(output).map_err(|e| SerializerError::Serde {
384 message: format!("Deserialization error: {}", e),
385 })
386 }
387}
388
389pub trait Deserializer {
411 type Input;
413 type Output;
415
416 fn deserialize(&self, input: &Self::Input) -> Result<Self::Output, SerializerError>;
418}
419
420#[cfg(test)]
421mod tests {
422 use super::*;
423
424 #[derive(Serialize, Deserialize, PartialEq, Debug)]
425 struct TestUser {
426 id: i64,
427 name: String,
428 }
429
430 #[test]
431 fn test_json_serializer_roundtrip() {
432 let user = TestUser {
433 id: 1,
434 name: "Alice".to_string(),
435 };
436 let serializer = JsonSerializer::<TestUser>::new();
437
438 let json = serializer.serialize(&user).unwrap();
439 let deserialized = serializer.deserialize(&json).unwrap();
440
441 assert_eq!(user.id, deserialized.id);
442 assert_eq!(user.name, deserialized.name);
443 }
444
445 #[test]
446 fn test_json_serializer_serialize() {
447 let user = TestUser {
448 id: 1,
449 name: "Alice".to_string(),
450 };
451 let serializer = JsonSerializer::<TestUser>::new();
452
453 let json = serializer.serialize(&user).unwrap();
454 assert!(json.contains("Alice"));
455 assert!(json.contains("\"id\":1"));
456 }
457
458 #[test]
459 fn test_json_serializer_deserialize() {
460 let json = r#"{"id":1,"name":"Alice"}"#.to_string();
461 let serializer = JsonSerializer::<TestUser>::new();
462
463 let user = serializer.deserialize(&json).unwrap();
464 assert_eq!(user.id, 1);
465 assert_eq!(user.name, "Alice");
466 }
467
468 #[test]
469 fn test_json_serializer_deserialize_error() {
470 let invalid_json = r#"{"invalid"}"#.to_string();
471 let serializer = JsonSerializer::<TestUser>::new();
472
473 let result = serializer.deserialize(&invalid_json);
474 assert!(result.is_err());
475 }
476
477 #[test]
478 fn test_validator_error_display() {
479 let err = ValidatorError::UniqueViolation {
480 field_name: "email".to_string(),
481 value: "test@example.com".to_string(),
482 message: "Email already exists".to_string(),
483 };
484 assert!(err.to_string().contains("email"));
485 assert!(err.to_string().contains("test@example.com"));
486 }
487
488 #[test]
489 fn test_serializer_error_from_validator_error() {
490 let validator_err = ValidatorError::Custom {
491 message: "test error".to_string(),
492 };
493 let serializer_err: SerializerError = validator_err.into();
494
495 match serializer_err {
496 SerializerError::Validation(_) => {}
497 _ => panic!("Expected Validation error"),
498 }
499 }
500}