wasm_dbms_api/dbms/validate/
case.rs1use crate::prelude::{Validate, Value};
2
3pub struct SnakeCaseValidator;
31
32impl Validate for SnakeCaseValidator {
33 fn validate(&self, value: &Value) -> crate::prelude::DbmsResult<()> {
34 let Value::Text(text) = value else {
35 return Err(crate::prelude::DbmsError::Validation(
36 "RGB color validation requires a text value".to_string(),
37 ));
38 };
39
40 let s = &text.0;
41
42 let first_char = s.chars().next().ok_or_else(|| {
44 crate::prelude::DbmsError::Validation(
45 "Empty string is not valid snake_case".to_string(),
46 )
47 })?;
48 if !first_char.is_lowercase() && first_char != '_' {
49 return Err(crate::prelude::DbmsError::Validation(format!(
50 "Value '{s}' is not in snake_case format",
51 )));
52 }
53
54 if s.chars()
55 .all(|c| c.is_lowercase() || c.is_ascii_digit() || c == '_')
56 {
57 Ok(())
58 } else {
59 Err(crate::prelude::DbmsError::Validation(format!(
60 "Value '{s}' is not in snake_case format",
61 )))
62 }
63 }
64}
65
66pub struct KebabCaseValidator;
92
93impl Validate for KebabCaseValidator {
94 fn validate(&self, value: &Value) -> crate::prelude::DbmsResult<()> {
95 let Value::Text(text) = value else {
96 return Err(crate::prelude::DbmsError::Validation(
97 "RGB color validation requires a text value".to_string(),
98 ));
99 };
100
101 let s = &text.0;
102
103 let first_char = s.chars().next().ok_or_else(|| {
105 crate::prelude::DbmsError::Validation(
106 "Empty string is not valid kebab-case".to_string(),
107 )
108 })?;
109 if !first_char.is_lowercase() {
110 return Err(crate::prelude::DbmsError::Validation(format!(
111 "Value '{s}' is not in kebab-case format",
112 )));
113 }
114
115 if s.chars()
116 .all(|c| c.is_lowercase() || c.is_ascii_digit() || c == '-')
117 {
118 Ok(())
119 } else {
120 Err(crate::prelude::DbmsError::Validation(format!(
121 "Value '{s}' is not in kebab-case format",
122 )))
123 }
124 }
125}
126
127pub struct CamelCaseValidator;
152
153impl Validate for CamelCaseValidator {
154 fn validate(&self, value: &Value) -> crate::prelude::DbmsResult<()> {
155 let Value::Text(text) = value else {
156 return Err(crate::prelude::DbmsError::Validation(
157 "CamelCase validation requires a text value".to_string(),
158 ));
159 };
160
161 let s = &text.0;
162
163 let mut chars = s.chars();
164 let first_char = chars.next().ok_or_else(|| {
165 crate::prelude::DbmsError::Validation("Empty string is not valid CamelCase".to_string())
166 })?;
167 if !first_char.is_uppercase() {
168 return Err(crate::prelude::DbmsError::Validation(format!(
169 "Value '{s}' is not in CamelCase format"
170 )));
171 }
172
173 if s.chars().all(|c| c.is_alphanumeric()) {
174 Ok(())
175 } else {
176 Err(crate::prelude::DbmsError::Validation(format!(
177 "Value '{}' is not in CamelCase format",
178 s
179 )))
180 }
181 }
182}
183
184#[cfg(test)]
185mod tests {
186 use super::*;
187 use crate::prelude::{Text, Value};
188
189 #[test]
190 fn test_snake_case_validator() {
191 let validator = SnakeCaseValidator;
192
193 let value = Value::Text(Text("valid_snake_case".to_string()));
195 assert!(validator.validate(&value).is_ok());
196
197 let value = Value::Text(Text("Invalid_Snake_Case".to_string()));
199 assert!(validator.validate(&value).is_err());
200
201 let value = Value::Text(Text("invalid-snake-case!".to_string()));
203 assert!(validator.validate(&value).is_err());
204
205 let value = Value::Text(Text("1invalid_snake_case".to_string()));
207 assert!(validator.validate(&value).is_err());
208
209 let value = Value::Text(Text("_valid_snake_case".to_string()));
211 assert!(validator.validate(&value).is_ok());
212
213 let value = Value::Text(Text("".to_string()));
215 assert!(validator.validate(&value).is_err());
216
217 let value = Value::Int32(123i32.into());
218 assert!(validator.validate(&value).is_err());
219 }
220
221 #[test]
222 fn test_kebab_case_validator() {
223 let validator = KebabCaseValidator;
224
225 let value = Value::Text(Text("valid-kebab-case".to_string()));
227 assert!(validator.validate(&value).is_ok());
228
229 let value = Value::Text(Text("Invalid-Kebab-Case".to_string()));
231 assert!(validator.validate(&value).is_err());
232
233 let value = Value::Text(Text("invalid-kebab-case!".to_string()));
235 assert!(validator.validate(&value).is_err());
236
237 let value = Value::Text(Text("".to_string()));
239 assert!(validator.validate(&value).is_err());
240
241 let value = Value::Text(Text("1invalid-kebab-case".to_string()));
243 assert!(validator.validate(&value).is_err());
244
245 let value = Value::Int32(123i32.into());
246 assert!(validator.validate(&value).is_err());
247 }
248
249 #[test]
250 fn test_camel_case_validator() {
251 let validator = CamelCaseValidator;
252 let value = Value::Text(Text("ValidCamelCase".to_string()));
254 assert!(validator.validate(&value).is_ok());
255 let value = Value::Text(Text("invalidCamelCase".to_string()));
257 assert!(validator.validate(&value).is_err());
258 let value = Value::Text(Text("Invalid-CamelCase!".to_string()));
260 assert!(validator.validate(&value).is_err());
261 let value = Value::Text(Text("Invalid_CamelCase".to_string()));
263 assert!(validator.validate(&value).is_err());
264
265 let value = Value::Text(Text("".to_string()));
267 assert!(validator.validate(&value).is_err());
268
269 let value = Value::Int32(123i32.into());
270 assert!(validator.validate(&value).is_err());
271 }
272}