1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//! Validation extractors for Kegani
//!
//! Provides `ValidatedForm<T>` and `ValidatedQuery<T>` extractors.
//!
//! Note: For JSON body extraction, use `actix_web::web::Json<T>` directly.
//! For validated form/query extraction, use the types here with your own validation logic.
use crateValidationError;
/// Validated form extractor marker.
///
/// This struct wraps a parsed form value. Apply your own validation
/// in the handler.
///
/// # Example
/// ```ignore
/// async fn create_user(
/// ValidatedForm(payload): ValidatedForm<CreateUser>,
/// ) -> Result<Json<User>, AppError> {
/// // payload is parsed; apply validation before use
/// if payload.email.is_empty() {
/// return Err(AppError::validation("email cannot be empty"));
/// }
/// // ...
/// }
/// ```
;
/// Validated query extractor marker.
///
/// This struct wraps parsed query parameters. Apply your own validation
/// in the handler.
///
/// # Example
/// ```ignore
/// async fn list_users(
/// ValidatedQuery(params): ValidatedQuery<Pagination>,
/// ) -> Result<Json<Vec<User>>, AppError> {
/// // params.page, params.size
/// }
/// ```
;
/// Trait for types that implement their own validation logic
///
/// Implement `Validate` on your DTO to enable structured field-level validation.
///
/// # Example
/// ```ignore
/// use serde::Deserialize;
///
/// #[derive(Deserialize)]
/// pub struct CreateUser {
/// pub email: String,
/// pub password: String,
/// }
///
/// impl Validate for CreateUser {
/// fn validate(self) -> Result<Self, Vec<ValidationError>> {
/// let mut errors = Vec::new();
/// if !self.email.contains('@') {
/// errors.push(ValidationError::new("email", "Must be a valid email"));
/// }
/// if self.password.len() < 8 {
/// errors.push(ValidationError::new("password", "Must be at least 8 characters"));
/// }
/// if errors.is_empty() { Ok(self) } else { Err(errors) }
/// }
/// }
/// ```