rustapi_validate/
validate.rs1use crate::error::ValidationError;
4
5pub trait Validate: validator::Validate {
40 fn validate(&self) -> Result<(), ValidationError> {
42 validator::Validate::validate(self)
43 .map_err(ValidationError::from_validator_errors)
44 }
45
46 fn validated(self) -> Result<Self, ValidationError>
48 where
49 Self: Sized,
50 {
51 Validate::validate(&self)?;
52 Ok(self)
53 }
54}
55
56impl<T: validator::Validate> Validate for T {}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 use validator::Validate as ValidatorValidate;
63
64 #[derive(Debug, ValidatorValidate)]
65 struct TestUser {
66 #[validate(email)]
67 email: String,
68 #[validate(length(min = 3, max = 20))]
69 username: String,
70 #[validate(range(min = 18, max = 120))]
71 age: u8,
72 }
73
74 #[test]
75 fn valid_struct_passes() {
76 let user = TestUser {
77 email: "test@example.com".to_string(),
78 username: "testuser".to_string(),
79 age: 25,
80 };
81
82 assert!(Validate::validate(&user).is_ok());
83 }
84
85 #[test]
86 fn invalid_email_fails() {
87 let user = TestUser {
88 email: "not-an-email".to_string(),
89 username: "testuser".to_string(),
90 age: 25,
91 };
92
93 let result = Validate::validate(&user);
94 assert!(result.is_err());
95
96 let error = result.unwrap_err();
97 assert!(error.fields.iter().any(|f| f.field == "email"));
98 }
99
100 #[test]
101 fn invalid_length_fails() {
102 let user = TestUser {
103 email: "test@example.com".to_string(),
104 username: "ab".to_string(), age: 25,
106 };
107
108 let result = Validate::validate(&user);
109 assert!(result.is_err());
110
111 let error = result.unwrap_err();
112 assert!(error.fields.iter().any(|f| f.field == "username" && f.code == "length"));
113 }
114
115 #[test]
116 fn invalid_range_fails() {
117 let user = TestUser {
118 email: "test@example.com".to_string(),
119 username: "testuser".to_string(),
120 age: 15, };
122
123 let result = Validate::validate(&user);
124 assert!(result.is_err());
125
126 let error = result.unwrap_err();
127 assert!(error.fields.iter().any(|f| f.field == "age" && f.code == "range"));
128 }
129
130 #[test]
131 fn multiple_errors_collected() {
132 let user = TestUser {
133 email: "invalid".to_string(),
134 username: "ab".to_string(),
135 age: 150,
136 };
137
138 let result = Validate::validate(&user);
139 assert!(result.is_err());
140
141 let error = result.unwrap_err();
142 assert!(error.fields.len() >= 3);
143 }
144
145 #[test]
146 fn validated_returns_struct_on_success() {
147 let user = TestUser {
148 email: "test@example.com".to_string(),
149 username: "testuser".to_string(),
150 age: 25,
151 };
152
153 let result = user.validated();
154 assert!(result.is_ok());
155
156 let validated_user = result.unwrap();
157 assert_eq!(validated_user.email, "test@example.com");
158 }
159}