nestforge_core/
validation.rs1use 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}