dog_schema/
lib.rs

1pub use dog_schema_macros::schema;
2
3use dog_core::errors::DogError;
4use serde_json::{json, Map, Value};
5
6#[derive(Default)]
7pub struct SchemaErrors {
8    map: Map<String, Value>,
9}
10
11impl SchemaErrors {
12    pub fn push_schema(&mut self, msg: impl Into<String>) {
13        Self::push_to(&mut self.map, "_schema", msg);
14    }
15
16    pub fn push_field(&mut self, field: &str, msg: impl Into<String>) {
17        Self::push_to(&mut self.map, field, msg);
18    }
19
20    fn push_to(map: &mut Map<String, Value>, key: &str, msg: impl Into<String>) {
21        let msg = Value::String(msg.into());
22        match map.get_mut(key) {
23            Some(Value::Array(arr)) => arr.push(msg),
24            Some(_) => {
25                map.insert(key.to_string(), Value::Array(vec![msg]));
26            }
27            None => {
28                map.insert(key.to_string(), Value::Array(vec![msg]));
29            }
30        }
31    }
32
33    pub fn is_empty(&self) -> bool {
34        self.map.is_empty()
35    }
36
37    pub fn into_unprocessable_anyhow(self, message: &str) -> anyhow::Error {
38        DogError::unprocessable(message)
39            .with_errors(Value::Object(self.map))
40            .into_anyhow()
41    }
42}
43
44pub fn unprocessable(message: &str, errors: Value) -> anyhow::Error {
45    DogError::unprocessable(message).with_errors(errors).into_anyhow()
46}
47
48pub fn schema_error(message: &str, msg: impl Into<String>) -> anyhow::Error {
49    unprocessable(message, json!({"_schema": [msg.into()]}))
50}