divviup_client/
validation_errors.rs1use pad_adapter::PadAdapter;
2use serde::{Deserialize, Serialize};
3use std::{
4 collections::HashMap,
5 fmt::{self, Display, Formatter, Write},
6};
7
8#[derive(Serialize, Deserialize, Debug)]
9pub struct ValidationError {
10 code: String,
11 #[serde(skip_serializing_if = "Option::is_none")]
12 message: Option<String>,
13 #[serde(skip_serializing_if = "HashMap::is_empty")]
14 params: HashMap<String, serde_json::Value>,
15}
16
17#[derive(Serialize, Deserialize, Debug)]
18#[serde(untagged)]
19pub enum ValidationErrors {
20 Map(HashMap<String, ValidationErrors>),
21 List(Vec<ValidationError>),
22}
23
24impl Display for ValidationError {
25 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
26 let code = &self.code;
27 match (&self.message, self.params.is_empty()) {
28 (None, true) => f.write_str(&self.code),
29 (Some(message), _) => f.write_fmt(format_args!("{code} {message}")),
30 (None, false) => f.write_fmt(format_args!(
31 "{code} {}",
32 serde_json::to_string(&self.params).unwrap()
33 )),
34 }
35 }
36}
37
38impl Display for ValidationErrors {
39 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
40 let mut pad_adapter = PadAdapter::with_padding(f, " ");
41 match &self {
42 ValidationErrors::Map(map) => {
43 for (key, values) in map {
44 write!(pad_adapter, "- {key}:\n{values}")?;
45 }
46 }
47 ValidationErrors::List(errors) => {
48 for value in errors {
49 writeln!(pad_adapter, "* {value}")?;
50 }
51 }
52 }
53
54 Ok(())
55 }
56}