systemprompt_traits/
validation.rs1use std::fmt::Debug;
4
5#[derive(Debug, Clone)]
6pub struct ValidationError {
7 pub field: String,
8 pub message: String,
9 pub context: Option<String>,
10}
11
12impl ValidationError {
13 #[must_use]
14 pub fn new(field: impl Into<String>, message: impl Into<String>) -> Self {
15 Self {
16 field: field.into(),
17 message: message.into(),
18 context: None,
19 }
20 }
21
22 #[must_use]
23 pub fn with_context(mut self, context: impl Into<String>) -> Self {
24 self.context = Some(context.into());
25 self
26 }
27}
28
29impl std::fmt::Display for ValidationError {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 if let Some(ref ctx) = self.context {
32 write!(
33 f,
34 "VALIDATION ERROR [{}]: {} (context: {})",
35 self.field, self.message, ctx
36 )
37 } else {
38 write!(f, "VALIDATION ERROR [{}]: {}", self.field, self.message)
39 }
40 }
41}
42
43impl std::error::Error for ValidationError {}
44
45pub type ValidationResult<T> = Result<T, ValidationError>;
46
47pub trait Validate: Debug {
48 fn validate(&self) -> ValidationResult<()>;
49}
50
51pub trait MetadataValidation: Validate {
52 fn required_string_fields(&self) -> Vec<(&'static str, &str)>;
53
54 fn validate_required_fields(&self) -> ValidationResult<()> {
55 for (field_name, field_value) in self.required_string_fields() {
56 if field_value.is_empty() {
57 return Err(ValidationError::new(
58 field_name,
59 format!("{field_name} cannot be empty"),
60 ));
61 }
62 }
63 Ok(())
64 }
65}