1use crate::classes::ClassBuilder;
7use serde::{Deserialize, Serialize};
8use std::fmt;
9use std::collections::HashMap;
10
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13pub enum ValidationRule {
14 Required,
16 Pattern(String),
18 Length(usize, usize),
20 Range(f64, f64),
22 Custom(String),
24}
25
26impl fmt::Display for ValidationRule {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 match self {
29 ValidationRule::Required => write!(f, "required"),
30 ValidationRule::Pattern(pattern) => write!(f, "pattern:{}", pattern),
31 ValidationRule::Length(min, max) => write!(f, "length:{}-{}", min, max),
32 ValidationRule::Range(min, max) => write!(f, "range:{}-{}", min, max),
33 ValidationRule::Custom(rule) => write!(f, "{}", rule),
34 }
35 }
36}
37
38impl ValidationRule {
39 pub fn to_class_name(&self) -> String {
41 match self {
42 ValidationRule::Required => "validation-required".to_string(),
43 ValidationRule::Pattern(pattern) => format!("validation-pattern-{}", pattern.replace(":", "-").replace("(", "").replace(")", "").replace("*", "star").replace("+", "plus").replace("?", "question").replace("^", "caret").replace("$", "dollar").replace("|", "pipe").replace("\\", "backslash").replace("/", "slash").replace(" ", "-")),
44 ValidationRule::Length(min, max) => format!("validation-length-{}-{}", min, max),
45 ValidationRule::Range(min, max) => format!("validation-range-{}-{}", min, max),
46 ValidationRule::Custom(rule) => format!("validation-{}", rule.replace(":", "-").replace("(", "").replace(")", "").replace("*", "star").replace("+", "plus").replace("?", "question").replace("^", "caret").replace("$", "dollar").replace("|", "pipe").replace("\\", "backslash").replace("/", "slash").replace(" ", "-")),
47 }
48 }
49
50 pub fn to_css_value(&self) -> String {
52 self.to_string()
53 }
54}
55
56#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
58pub enum ValidationSeverity {
59 Error,
61 Warning,
63 Info,
65 Success,
67 Custom(String),
69}
70
71impl fmt::Display for ValidationSeverity {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 match self {
74 ValidationSeverity::Error => write!(f, "error"),
75 ValidationSeverity::Warning => write!(f, "warning"),
76 ValidationSeverity::Info => write!(f, "info"),
77 ValidationSeverity::Success => write!(f, "success"),
78 ValidationSeverity::Custom(severity) => write!(f, "{}", severity),
79 }
80 }
81}
82
83impl ValidationSeverity {
84 pub fn to_class_name(&self) -> String {
86 match self {
87 ValidationSeverity::Error => "validation-error".to_string(),
88 ValidationSeverity::Warning => "validation-warning".to_string(),
89 ValidationSeverity::Info => "validation-info".to_string(),
90 ValidationSeverity::Success => "validation-success".to_string(),
91 ValidationSeverity::Custom(severity) => format!("validation-{}", severity),
92 }
93 }
94
95 pub fn to_css_value(&self) -> String {
97 self.to_string()
98 }
99}
100
101#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
103pub enum ValidationScope {
104 Global,
106 Local,
108 Component,
110 Page,
112 Custom(String),
114}
115
116impl fmt::Display for ValidationScope {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 match self {
119 ValidationScope::Global => write!(f, "global"),
120 ValidationScope::Local => write!(f, "local"),
121 ValidationScope::Component => write!(f, "component"),
122 ValidationScope::Page => write!(f, "page"),
123 ValidationScope::Custom(scope) => write!(f, "{}", scope),
124 }
125 }
126}
127
128impl ValidationScope {
129 pub fn to_class_name(&self) -> String {
131 match self {
132 ValidationScope::Global => "validation-global".to_string(),
133 ValidationScope::Local => "validation-local".to_string(),
134 ValidationScope::Component => "validation-component".to_string(),
135 ValidationScope::Page => "validation-page".to_string(),
136 ValidationScope::Custom(scope) => format!("validation-{}", scope),
137 }
138 }
139
140 pub fn to_css_value(&self) -> String {
142 self.to_string()
143 }
144}
145
146#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
148pub enum ValidationMode {
149 Strict,
151 Loose,
153 Custom,
155 Disabled,
157 CustomMode(String),
159}
160
161impl fmt::Display for ValidationMode {
162 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163 match self {
164 ValidationMode::Strict => write!(f, "strict"),
165 ValidationMode::Loose => write!(f, "loose"),
166 ValidationMode::Custom => write!(f, "custom"),
167 ValidationMode::Disabled => write!(f, "disabled"),
168 ValidationMode::CustomMode(mode) => write!(f, "{}", mode),
169 }
170 }
171}
172
173impl ValidationMode {
174 pub fn to_class_name(&self) -> String {
176 match self {
177 ValidationMode::Strict => "validation-strict".to_string(),
178 ValidationMode::Loose => "validation-loose".to_string(),
179 ValidationMode::Custom => "validation-custom".to_string(),
180 ValidationMode::Disabled => "validation-disabled".to_string(),
181 ValidationMode::CustomMode(mode) => format!("validation-{}", mode),
182 }
183 }
184
185 pub fn to_css_value(&self) -> String {
187 self.to_string()
188 }
189}
190
191#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
193pub enum ValidationResult {
194 Valid,
196 Invalid(String),
198 Warning(String),
200 Info(String),
202 Custom(String),
204}
205
206impl fmt::Display for ValidationResult {
207 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
208 match self {
209 ValidationResult::Valid => write!(f, "valid"),
210 ValidationResult::Invalid(message) => write!(f, "invalid:{}", message),
211 ValidationResult::Warning(message) => write!(f, "warning:{}", message),
212 ValidationResult::Info(message) => write!(f, "info:{}", message),
213 ValidationResult::Custom(result) => write!(f, "{}", result),
214 }
215 }
216}
217
218impl ValidationResult {
219 pub fn to_class_name(&self) -> String {
221 match self {
222 ValidationResult::Valid => "validation-valid".to_string(),
223 ValidationResult::Invalid(_) => "validation-invalid".to_string(),
224 ValidationResult::Warning(_) => "validation-warning".to_string(),
225 ValidationResult::Info(_) => "validation-info".to_string(),
226 ValidationResult::Custom(result) => format!("validation-{}", result),
227 }
228 }
229
230 pub fn to_css_value(&self) -> String {
232 self.to_string()
233 }
234}
235
236pub trait EnhancedValidationUtilities {
238 fn validation_rule(self, rule: ValidationRule) -> Self;
240 fn validation_severity(self, severity: ValidationSeverity) -> Self;
242 fn validation_scope(self, scope: ValidationScope) -> Self;
244 fn validation_mode(self, mode: ValidationMode) -> Self;
246 fn validation_result(self, result: ValidationResult) -> Self;
248 fn validation_custom(self, name: &str, options: HashMap<String, String>) -> Self;
250}
251
252impl EnhancedValidationUtilities for ClassBuilder {
253 fn validation_rule(self, rule: ValidationRule) -> Self {
254 self.class(&rule.to_class_name())
255 }
256
257 fn validation_severity(self, severity: ValidationSeverity) -> Self {
258 self.class(&severity.to_class_name())
259 }
260
261 fn validation_scope(self, scope: ValidationScope) -> Self {
262 self.class(&scope.to_class_name())
263 }
264
265 fn validation_mode(self, mode: ValidationMode) -> Self {
266 self.class(&mode.to_class_name())
267 }
268
269 fn validation_result(self, result: ValidationResult) -> Self {
270 self.class(&result.to_class_name())
271 }
272
273 fn validation_custom(self, name: &str, _options: HashMap<String, String>) -> Self {
274 let validation_class = format!("validation-{}", name);
275 self.class(&validation_class)
276 }
277}
278
279pub trait EnhancedValidationConvenience {
281 fn validation_required(self) -> Self;
283 fn validation_pattern(self, pattern: &str) -> Self;
285 fn validation_length(self, min: usize, max: usize) -> Self;
287 fn validation_range(self, min: f64, max: f64) -> Self;
289 fn validation_error(self) -> Self;
291 fn validation_warning(self) -> Self;
293 fn validation_info(self) -> Self;
295 fn validation_success(self) -> Self;
297 fn validation_global(self) -> Self;
299 fn validation_local(self) -> Self;
301 fn validation_component(self) -> Self;
303 fn validation_page(self) -> Self;
305 fn validation_strict(self) -> Self;
307 fn validation_loose(self) -> Self;
309 fn validation_custom_mode(self) -> Self;
311 fn validation_disabled(self) -> Self;
313 fn validation_valid(self) -> Self;
315 fn validation_invalid(self, message: &str) -> Self;
317 fn validation_warning_result(self, message: &str) -> Self;
319 fn validation_info_result(self, message: &str) -> Self;
321}
322
323impl EnhancedValidationConvenience for ClassBuilder {
324 fn validation_required(self) -> Self {
325 self.validation_rule(ValidationRule::Required)
326 }
327
328 fn validation_pattern(self, pattern: &str) -> Self {
329 self.validation_rule(ValidationRule::Pattern(pattern.to_string()))
330 }
331
332 fn validation_length(self, min: usize, max: usize) -> Self {
333 self.validation_rule(ValidationRule::Length(min, max))
334 }
335
336 fn validation_range(self, min: f64, max: f64) -> Self {
337 self.validation_rule(ValidationRule::Range(min, max))
338 }
339
340 fn validation_error(self) -> Self {
341 self.validation_severity(ValidationSeverity::Error)
342 }
343
344 fn validation_warning(self) -> Self {
345 self.validation_severity(ValidationSeverity::Warning)
346 }
347
348 fn validation_info(self) -> Self {
349 self.validation_severity(ValidationSeverity::Info)
350 }
351
352 fn validation_success(self) -> Self {
353 self.validation_severity(ValidationSeverity::Success)
354 }
355
356 fn validation_global(self) -> Self {
357 self.validation_scope(ValidationScope::Global)
358 }
359
360 fn validation_local(self) -> Self {
361 self.validation_scope(ValidationScope::Local)
362 }
363
364 fn validation_component(self) -> Self {
365 self.validation_scope(ValidationScope::Component)
366 }
367
368 fn validation_page(self) -> Self {
369 self.validation_scope(ValidationScope::Page)
370 }
371
372 fn validation_strict(self) -> Self {
373 self.validation_mode(ValidationMode::Strict)
374 }
375
376 fn validation_loose(self) -> Self {
377 self.validation_mode(ValidationMode::Loose)
378 }
379
380 fn validation_custom_mode(self) -> Self {
381 self.validation_mode(ValidationMode::Custom)
382 }
383
384 fn validation_disabled(self) -> Self {
385 self.validation_mode(ValidationMode::Disabled)
386 }
387
388 fn validation_valid(self) -> Self {
389 self.validation_result(ValidationResult::Valid)
390 }
391
392 fn validation_invalid(self, message: &str) -> Self {
393 self.validation_result(ValidationResult::Invalid(message.to_string()))
394 }
395
396 fn validation_warning_result(self, message: &str) -> Self {
397 self.validation_result(ValidationResult::Warning(message.to_string()))
398 }
399
400 fn validation_info_result(self, message: &str) -> Self {
401 self.validation_result(ValidationResult::Info(message.to_string()))
402 }
403}
404
405#[cfg(test)]
406mod tests {
407 use super::*;
408 use crate::classes::ClassBuilder;
409
410 #[test]
411 fn test_validation_rule_enum_values() {
412 assert_eq!(ValidationRule::Required.to_string(), "required");
413 assert_eq!(ValidationRule::Pattern("test".to_string()).to_string(), "pattern:test");
414 assert_eq!(ValidationRule::Length(1, 10).to_string(), "length:1-10");
415 assert_eq!(ValidationRule::Range(0.0, 100.0).to_string(), "range:0-100");
416 assert_eq!(ValidationRule::Custom("custom".to_string()).to_string(), "custom");
417 }
418
419 #[test]
420 fn test_validation_rule_class_names() {
421 assert_eq!(ValidationRule::Required.to_class_name(), "validation-required");
422 assert_eq!(ValidationRule::Pattern("test".to_string()).to_class_name(), "validation-pattern-test");
423 assert_eq!(ValidationRule::Length(1, 10).to_class_name(), "validation-length-1-10");
424 assert_eq!(ValidationRule::Range(0.0, 100.0).to_class_name(), "validation-range-0-100");
425 assert_eq!(ValidationRule::Custom("custom".to_string()).to_class_name(), "validation-custom");
426 }
427
428 #[test]
429 fn test_validation_severity_enum_values() {
430 assert_eq!(ValidationSeverity::Error.to_string(), "error");
431 assert_eq!(ValidationSeverity::Warning.to_string(), "warning");
432 assert_eq!(ValidationSeverity::Info.to_string(), "info");
433 assert_eq!(ValidationSeverity::Success.to_string(), "success");
434 assert_eq!(ValidationSeverity::Custom("custom".to_string()).to_string(), "custom");
435 }
436
437 #[test]
438 fn test_validation_severity_class_names() {
439 assert_eq!(ValidationSeverity::Error.to_class_name(), "validation-error");
440 assert_eq!(ValidationSeverity::Warning.to_class_name(), "validation-warning");
441 assert_eq!(ValidationSeverity::Info.to_class_name(), "validation-info");
442 assert_eq!(ValidationSeverity::Success.to_class_name(), "validation-success");
443 assert_eq!(ValidationSeverity::Custom("custom".to_string()).to_class_name(), "validation-custom");
444 }
445
446 #[test]
447 fn test_validation_scope_enum_values() {
448 assert_eq!(ValidationScope::Global.to_string(), "global");
449 assert_eq!(ValidationScope::Local.to_string(), "local");
450 assert_eq!(ValidationScope::Component.to_string(), "component");
451 assert_eq!(ValidationScope::Page.to_string(), "page");
452 assert_eq!(ValidationScope::Custom("custom".to_string()).to_string(), "custom");
453 }
454
455 #[test]
456 fn test_validation_scope_class_names() {
457 assert_eq!(ValidationScope::Global.to_class_name(), "validation-global");
458 assert_eq!(ValidationScope::Local.to_class_name(), "validation-local");
459 assert_eq!(ValidationScope::Component.to_class_name(), "validation-component");
460 assert_eq!(ValidationScope::Page.to_class_name(), "validation-page");
461 assert_eq!(ValidationScope::Custom("custom".to_string()).to_class_name(), "validation-custom");
462 }
463
464 #[test]
465 fn test_validation_mode_enum_values() {
466 assert_eq!(ValidationMode::Strict.to_string(), "strict");
467 assert_eq!(ValidationMode::Loose.to_string(), "loose");
468 assert_eq!(ValidationMode::Custom.to_string(), "custom");
469 assert_eq!(ValidationMode::Disabled.to_string(), "disabled");
470 assert_eq!(ValidationMode::CustomMode("custom".to_string()).to_string(), "custom");
471 }
472
473 #[test]
474 fn test_validation_mode_class_names() {
475 assert_eq!(ValidationMode::Strict.to_class_name(), "validation-strict");
476 assert_eq!(ValidationMode::Loose.to_class_name(), "validation-loose");
477 assert_eq!(ValidationMode::Custom.to_class_name(), "validation-custom");
478 assert_eq!(ValidationMode::Disabled.to_class_name(), "validation-disabled");
479 assert_eq!(ValidationMode::CustomMode("custom".to_string()).to_class_name(), "validation-custom");
480 }
481
482 #[test]
483 fn test_validation_result_enum_values() {
484 assert_eq!(ValidationResult::Valid.to_string(), "valid");
485 assert_eq!(ValidationResult::Invalid("message".to_string()).to_string(), "invalid:message");
486 assert_eq!(ValidationResult::Warning("message".to_string()).to_string(), "warning:message");
487 assert_eq!(ValidationResult::Info("message".to_string()).to_string(), "info:message");
488 assert_eq!(ValidationResult::Custom("custom".to_string()).to_string(), "custom");
489 }
490
491 #[test]
492 fn test_validation_result_class_names() {
493 assert_eq!(ValidationResult::Valid.to_class_name(), "validation-valid");
494 assert_eq!(ValidationResult::Invalid("message".to_string()).to_class_name(), "validation-invalid");
495 assert_eq!(ValidationResult::Warning("message".to_string()).to_class_name(), "validation-warning");
496 assert_eq!(ValidationResult::Info("message".to_string()).to_class_name(), "validation-info");
497 assert_eq!(ValidationResult::Custom("custom".to_string()).to_class_name(), "validation-custom");
498 }
499
500 #[test]
501 fn test_enhanced_validation_utilities() {
502 let classes = ClassBuilder::new()
503 .validation_rule(ValidationRule::Required)
504 .validation_severity(ValidationSeverity::Error)
505 .validation_scope(ValidationScope::Global)
506 .validation_mode(ValidationMode::Strict)
507 .validation_result(ValidationResult::Valid);
508
509 let result = classes.build();
510 assert!(result.classes.contains("validation-required"));
511 assert!(result.classes.contains("validation-error"));
512 assert!(result.classes.contains("validation-global"));
513 assert!(result.classes.contains("validation-strict"));
514 assert!(result.classes.contains("validation-valid"));
515 }
516
517 #[test]
518 fn test_enhanced_validation_convenience() {
519 let classes = ClassBuilder::new()
520 .validation_required()
521 .validation_pattern("test")
522 .validation_length(1, 10)
523 .validation_range(0.0, 100.0)
524 .validation_error()
525 .validation_warning()
526 .validation_info()
527 .validation_success()
528 .validation_global()
529 .validation_local()
530 .validation_component()
531 .validation_page()
532 .validation_strict()
533 .validation_loose()
534 .validation_custom_mode()
535 .validation_disabled()
536 .validation_valid()
537 .validation_invalid("message")
538 .validation_warning_result("message")
539 .validation_info_result("message");
540
541 let result = classes.build();
542 assert!(result.classes.contains("validation-required"));
543 assert!(result.classes.contains("validation-pattern-test"));
544 assert!(result.classes.contains("validation-length-1-10"));
545 assert!(result.classes.contains("validation-range-0-100"));
546 assert!(result.classes.contains("validation-error"));
547 assert!(result.classes.contains("validation-warning"));
548 assert!(result.classes.contains("validation-info"));
549 assert!(result.classes.contains("validation-success"));
550 assert!(result.classes.contains("validation-global"));
551 assert!(result.classes.contains("validation-local"));
552 assert!(result.classes.contains("validation-component"));
553 assert!(result.classes.contains("validation-page"));
554 assert!(result.classes.contains("validation-strict"));
555 assert!(result.classes.contains("validation-loose"));
556 assert!(result.classes.contains("validation-custom"));
557 assert!(result.classes.contains("validation-disabled"));
558 assert!(result.classes.contains("validation-valid"));
559 assert!(result.classes.contains("validation-invalid"));
560 assert!(result.classes.contains("validation-warning"));
561 assert!(result.classes.contains("validation-info"));
562 }
563
564 #[test]
565 fn test_enhanced_validation_serialization() {
566 let validation_rule = ValidationRule::Required;
567 let serialized = serde_json::to_string(&validation_rule).unwrap();
568 let deserialized: ValidationRule = serde_json::from_str(&serialized).unwrap();
569 assert_eq!(validation_rule, deserialized);
570
571 let validation_severity = ValidationSeverity::Error;
572 let serialized = serde_json::to_string(&validation_severity).unwrap();
573 let deserialized: ValidationSeverity = serde_json::from_str(&serialized).unwrap();
574 assert_eq!(validation_severity, deserialized);
575
576 let validation_scope = ValidationScope::Global;
577 let serialized = serde_json::to_string(&validation_scope).unwrap();
578 let deserialized: ValidationScope = serde_json::from_str(&serialized).unwrap();
579 assert_eq!(validation_scope, deserialized);
580
581 let validation_mode = ValidationMode::Strict;
582 let serialized = serde_json::to_string(&validation_mode).unwrap();
583 let deserialized: ValidationMode = serde_json::from_str(&serialized).unwrap();
584 assert_eq!(validation_mode, deserialized);
585
586 let validation_result = ValidationResult::Valid;
587 let serialized = serde_json::to_string(&validation_result).unwrap();
588 let deserialized: ValidationResult = serde_json::from_str(&serialized).unwrap();
589 assert_eq!(validation_result, deserialized);
590 }
591
592 #[test]
593 fn test_enhanced_validation_comprehensive_usage() {
594 let classes = ClassBuilder::new()
595 .validation_rule(ValidationRule::Required)
596 .validation_severity(ValidationSeverity::Error)
597 .validation_scope(ValidationScope::Global)
598 .validation_mode(ValidationMode::Strict)
599 .validation_result(ValidationResult::Valid)
600 .validation_required()
601 .validation_pattern("test")
602 .validation_length(1, 10)
603 .validation_range(0.0, 100.0)
604 .validation_error()
605 .validation_warning()
606 .validation_info()
607 .validation_success()
608 .validation_global()
609 .validation_local()
610 .validation_component()
611 .validation_page()
612 .validation_strict()
613 .validation_loose()
614 .validation_custom_mode()
615 .validation_disabled()
616 .validation_valid()
617 .validation_invalid("message")
618 .validation_warning_result("message")
619 .validation_info_result("message");
620
621 let result = classes.build();
622 assert!(result.classes.contains("validation-required"));
623 assert!(result.classes.contains("validation-error"));
624 assert!(result.classes.contains("validation-global"));
625 assert!(result.classes.contains("validation-strict"));
626 assert!(result.classes.contains("validation-valid"));
627 assert!(result.classes.contains("validation-pattern-test"));
628 assert!(result.classes.contains("validation-length-1-10"));
629 assert!(result.classes.contains("validation-range-0-100"));
630 assert!(result.classes.contains("validation-warning"));
631 assert!(result.classes.contains("validation-info"));
632 assert!(result.classes.contains("validation-success"));
633 assert!(result.classes.contains("validation-local"));
634 assert!(result.classes.contains("validation-component"));
635 assert!(result.classes.contains("validation-page"));
636 assert!(result.classes.contains("validation-loose"));
637 assert!(result.classes.contains("validation-custom"));
638 assert!(result.classes.contains("validation-disabled"));
639 assert!(result.classes.contains("validation-invalid"));
640 }
641}