1use std::collections::HashMap;
2use std::fmt;
3
4pub struct ValidationError {
13 fields: HashMap<String, Vec<String>>,
14}
15
16impl ValidationError {
17 pub fn new(fields: HashMap<String, Vec<String>>) -> Self {
19 Self { fields }
20 }
21
22 pub fn is_empty(&self) -> bool {
24 self.fields.is_empty()
25 }
26
27 pub fn field_errors(&self, field: &str) -> &[String] {
30 self.fields.get(field).map(|v| v.as_slice()).unwrap_or(&[])
31 }
32
33 pub fn fields(&self) -> &HashMap<String, Vec<String>> {
35 &self.fields
36 }
37}
38
39impl fmt::Display for ValidationError {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 write!(
42 f,
43 "validation failed: {} field(s) invalid",
44 self.fields.len()
45 )
46 }
47}
48
49impl fmt::Debug for ValidationError {
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 f.debug_struct("ValidationError")
52 .field("fields", &self.fields)
53 .finish()
54 }
55}
56
57impl std::error::Error for ValidationError {}
58
59impl From<ValidationError> for crate::error::Error {
60 fn from(ve: ValidationError) -> Self {
61 crate::error::Error::unprocessable_entity("validation failed")
62 .with_details(serde_json::json!(ve.fields))
63 }
64}