claude_code_toolkit/traits/
validation.rs1use super::Credentials;
4use crate::error::Result;
5use crate::types::Config;
6use async_trait::async_trait;
7
8#[derive(Debug, Clone)]
10pub struct ValidationError {
11 pub field: String,
12 pub message: String,
13 pub severity: ValidationSeverity,
14 pub suggestion: Option<String>,
15}
16
17#[derive(Debug, Clone, PartialEq)]
18pub enum ValidationSeverity {
19 Error,
20 Warning,
21 Info,
22}
23
24impl ValidationError {
25 pub fn new(field: &str, message: &str, severity: ValidationSeverity) -> Self {
26 Self {
27 field: field.to_string(),
28 message: message.to_string(),
29 severity,
30 suggestion: None,
31 }
32 }
33
34 pub fn with_suggestion(mut self, suggestion: &str) -> Self {
35 self.suggestion = Some(suggestion.to_string());
36 self
37 }
38
39 pub fn error(field: &str, message: &str) -> Self {
40 Self::new(field, message, ValidationSeverity::Error)
41 }
42
43 pub fn warning(field: &str, message: &str) -> Self {
44 Self::new(field, message, ValidationSeverity::Warning)
45 }
46
47 pub fn info(field: &str, message: &str) -> Self {
48 Self::new(field, message, ValidationSeverity::Info)
49 }
50}
51
52#[async_trait]
54pub trait ValidationRule: Send + Sync {
55 fn rule_id(&self) -> &str;
57
58 fn description(&self) -> &str;
60
61 async fn validate_config(&self, config: &Config) -> Result<Vec<ValidationError>>;
63
64 async fn validate_credentials(&self, credentials: &Credentials) -> Result<Vec<ValidationError>>;
66
67 fn applies_to(&self, _config: &Config) -> bool {
69 true
70 }
71}
72
73#[async_trait]
75pub trait ValidationService: Send + Sync {
76 fn register_rule(&mut self, rule: Box<dyn ValidationRule>);
78
79 async fn validate_config(&self, config: &Config) -> Result<Vec<ValidationError>>;
81
82 async fn validate_credentials(&self, credentials: &Credentials) -> Result<Vec<ValidationError>>;
84
85 async fn get_validation_summary(
87 &self,
88 config: &Config,
89 credentials: Option<&Credentials>
90 ) -> Result<ValidationSummary>;
91
92 async fn auto_fix(&self, config: &mut Config) -> Result<Vec<String>>;
94}
95
96#[derive(Debug)]
98pub struct ValidationSummary {
99 pub total_issues: usize,
100 pub errors: usize,
101 pub warnings: usize,
102 pub info: usize,
103 pub auto_fixable: usize,
104 pub is_valid: bool,
105}
106
107impl ValidationSummary {
108 pub fn from_errors(errors: &[ValidationError]) -> Self {
109 let errors_count = errors
110 .iter()
111 .filter(|e| e.severity == ValidationSeverity::Error)
112 .count();
113 let warnings_count = errors
114 .iter()
115 .filter(|e| e.severity == ValidationSeverity::Warning)
116 .count();
117 let info_count = errors
118 .iter()
119 .filter(|e| e.severity == ValidationSeverity::Info)
120 .count();
121
122 Self {
123 total_issues: errors.len(),
124 errors: errors_count,
125 warnings: warnings_count,
126 info: info_count,
127 auto_fixable: 0, is_valid: errors_count == 0,
129 }
130 }
131}