Skip to main content

nestforge_core/
validation.rs

1use std::fmt::{Display, Formatter};
2
3use serde::Serialize;
4
5#[derive(Debug, Clone, Serialize)]
6pub struct ValidationIssue {
7    pub field: &'static str,
8    pub message: String,
9}
10
11#[derive(Debug, Clone, Serialize, Default)]
12pub struct ValidationErrors {
13    pub errors: Vec<ValidationIssue>,
14}
15
16impl ValidationErrors {
17    pub fn new(errors: Vec<ValidationIssue>) -> Self {
18        Self { errors }
19    }
20
21    pub fn single(field: &'static str, message: impl Into<String>) -> Self {
22        Self {
23            errors: vec![ValidationIssue {
24                field,
25                message: message.into(),
26            }],
27        }
28    }
29
30    pub fn is_empty(&self) -> bool {
31        self.errors.is_empty()
32    }
33}
34
35impl Display for ValidationErrors {
36    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
37        if self.errors.is_empty() {
38            return write!(f, "validation failed");
39        }
40
41        let summary = self
42            .errors
43            .iter()
44            .map(|issue| format!("{}: {}", issue.field, issue.message))
45            .collect::<Vec<_>>()
46            .join(", ");
47        write!(f, "{summary}")
48    }
49}
50
51pub trait Validate {
52    fn validate(&self) -> Result<(), ValidationErrors>;
53}