Skip to main content

leptos_forms_rs/validation/
errors.rs

1//! Validation errors module - Error handling and validation error types
2//!
3//! This module provides comprehensive error handling for form validation,
4//! including error aggregation, field error management, and error display formatting.
5
6use std::collections::HashMap;
7
8/// Validation errors for a form
9#[derive(Debug, Clone, PartialEq)]
10pub struct ValidationErrors {
11    pub field_errors: HashMap<String, Vec<String>>,
12    pub form_errors: Vec<String>,
13}
14
15impl Default for ValidationErrors {
16    fn default() -> Self {
17        Self::new()
18    }
19}
20
21impl ValidationErrors {
22    /// Create a new empty ValidationErrors instance
23    pub fn new() -> Self {
24        Self {
25            field_errors: HashMap::new(),
26            form_errors: Vec::new(),
27        }
28    }
29
30    /// Add a field error
31    pub fn add_field_error(&mut self, field_name: &str, error: String) {
32        self.field_errors
33            .entry(field_name.to_string())
34            .or_default()
35            .push(error);
36    }
37
38    /// Add a form-level error
39    pub fn add_form_error(&mut self, error: String) {
40        self.form_errors.push(error);
41    }
42
43    /// Check if there are no errors
44    pub fn is_empty(&self) -> bool {
45        self.field_errors.is_empty() && self.form_errors.is_empty()
46    }
47
48    /// Check if there are any errors
49    pub fn has_errors(&self) -> bool {
50        !self.is_empty()
51    }
52
53    /// Check if a specific field has errors
54    pub fn has_field_error(&self, field: &str) -> bool {
55        self.field_errors.contains_key(field)
56    }
57
58    /// Get errors for a specific field
59    pub fn get_field_error(&self, field: &str) -> Option<&Vec<String>> {
60        self.field_errors.get(field)
61    }
62
63    /// Clear errors for a specific field
64    pub fn clear_field(&mut self, field: &str) {
65        self.field_errors.remove(field);
66    }
67
68    /// Remove field errors (alias for clear_field)
69    pub fn remove_field_error(&mut self, field: &str) {
70        self.field_errors.remove(field);
71    }
72
73    /// Convert to field errors for compatibility
74    pub fn to_field_errors(&self) -> Vec<crate::error::FieldError> {
75        let mut errors = Vec::new();
76        for (field_name, field_errors) in &self.field_errors {
77            for error_msg in field_errors {
78                errors.push(crate::error::FieldError::new(
79                    field_name.clone(),
80                    error_msg.clone(),
81                ));
82            }
83        }
84        errors
85    }
86
87    /// Merge another ValidationErrors into this one
88    pub fn merge(&mut self, other: ValidationErrors) {
89        for (field, errors) in other.field_errors {
90            self.field_errors.entry(field).or_default().extend(errors);
91        }
92        self.form_errors.extend(other.form_errors);
93    }
94
95    /// Get all field names that have errors
96    pub fn get_error_fields(&self) -> Vec<String> {
97        self.field_errors.keys().cloned().collect()
98    }
99
100    /// Get total error count
101    pub fn error_count(&self) -> usize {
102        let field_error_count: usize = self.field_errors.values().map(|v| v.len()).sum();
103        field_error_count + self.form_errors.len()
104    }
105
106    /// Clear all errors
107    pub fn clear_all(&mut self) {
108        self.field_errors.clear();
109        self.form_errors.clear();
110    }
111}
112
113impl std::fmt::Display for ValidationErrors {
114    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115        if !self.form_errors.is_empty() {
116            writeln!(f, "Form errors:")?;
117            for error in &self.form_errors {
118                writeln!(f, "  - {}", error)?;
119            }
120        }
121
122        if !self.field_errors.is_empty() {
123            writeln!(f, "Field errors:")?;
124            for (field, errors) in &self.field_errors {
125                writeln!(f, "  {}:", field)?;
126                for error in errors {
127                    writeln!(f, "    - {}", error)?;
128                }
129            }
130        }
131
132        Ok(())
133    }
134}
135
136impl std::error::Error for ValidationErrors {}