rusdantic_core/traits.rs
1//! Core validation traits.
2//!
3//! The [`Validate`] trait is the central abstraction of Rusdantic. It is
4//! automatically implemented by the `#[derive(Rusdantic)]` macro and can
5//! also be implemented manually for custom types.
6
7use crate::error::ValidationErrors;
8
9/// The core validation trait for Rusdantic.
10///
11/// This trait is automatically implemented by `#[derive(Rusdantic)]`.
12/// It validates all fields of a struct according to their declared rules
13/// and returns all validation errors at once (collect-all, not fail-fast).
14///
15/// # Example
16///
17/// ```ignore
18/// use rusdantic::{Rusdantic, Validate};
19///
20/// #[derive(Rusdantic)]
21/// struct User {
22/// #[rusdantic(email)]
23/// email: String,
24/// }
25///
26/// let user = User { email: "not-an-email".to_string() };
27/// assert!(user.validate().is_err());
28/// ```
29pub trait Validate {
30 /// Validate this value, collecting all validation errors.
31 ///
32 /// Returns `Ok(())` if all validation rules pass, or `Err(ValidationErrors)`
33 /// containing all validation failures with their field paths.
34 fn validate(&self) -> Result<(), ValidationErrors>;
35
36 /// Validate with external context (database connection, config, etc.).
37 ///
38 /// This method enables validators that need access to external resources.
39 /// The default implementation ignores the context and delegates to `validate()`.
40 ///
41 /// # Example
42 ///
43 /// ```ignore
44 /// struct DbContext { /* ... */ }
45 ///
46 /// let user = User { email: "user@example.com".to_string() };
47 /// let ctx = DbContext { /* ... */ };
48 /// user.validate_with_context(&ctx)?;
49 /// ```
50 fn validate_with_context(&self, _ctx: &dyn std::any::Any) -> Result<(), ValidationErrors> {
51 self.validate()
52 }
53}
54
55// Implement Validate for common wrapper types so they can be used
56// transparently in validated structs.
57
58impl<T: Validate> Validate for Box<T> {
59 fn validate(&self) -> Result<(), ValidationErrors> {
60 (**self).validate()
61 }
62}
63
64impl<T: Validate> Validate for std::sync::Arc<T> {
65 fn validate(&self) -> Result<(), ValidationErrors> {
66 (**self).validate()
67 }
68}
69
70impl<T: Validate> Validate for std::rc::Rc<T> {
71 fn validate(&self) -> Result<(), ValidationErrors> {
72 (**self).validate()
73 }
74}