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