karbon_framework/validation/constraints/date/
date.rs1use crate::validation::constraints::{Constraint, ConstraintResult, ConstraintViolation};
2
3pub struct Date {
8 pub message: String,
9 pub format: String,
10}
11
12impl Default for Date {
13 fn default() -> Self {
14 Self {
15 message: "This value is not a valid date.".to_string(),
16 format: "%Y-%m-%d".to_string(),
17 }
18 }
19}
20
21impl Date {
22 pub fn new() -> Self {
23 Self::default()
24 }
25
26 pub fn with_message(mut self, message: impl Into<String>) -> Self {
27 self.message = message.into();
28 self
29 }
30
31 pub fn with_format(mut self, format: impl Into<String>) -> Self {
32 self.format = format.into();
33 self
34 }
35}
36
37impl Constraint for Date {
38 fn validate(&self, value: &str) -> ConstraintResult {
39 if chrono::NaiveDate::parse_from_str(value, &self.format).is_err() {
40 return Err(ConstraintViolation::new(
41 self.name(),
42 &self.message,
43 value,
44 ));
45 }
46 Ok(())
47 }
48
49 fn name(&self) -> &'static str {
50 "Date"
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn test_valid_dates() {
60 let constraint = Date::new();
61 assert!(constraint.validate("2024-01-01").is_ok());
62 assert!(constraint.validate("2024-12-31").is_ok());
63 assert!(constraint.validate("2024-02-29").is_ok()); assert!(constraint.validate("1999-06-15").is_ok());
65 }
66
67 #[test]
68 fn test_invalid_dates() {
69 let constraint = Date::new();
70 assert!(constraint.validate("").is_err());
71 assert!(constraint.validate("not-a-date").is_err());
72 assert!(constraint.validate("2024-13-01").is_err()); assert!(constraint.validate("2024-02-30").is_err()); assert!(constraint.validate("2023-02-29").is_err()); assert!(constraint.validate("01-01-2024").is_err()); }
77
78 #[test]
79 fn test_custom_format() {
80 let constraint = Date::new().with_format("%d/%m/%Y");
81 assert!(constraint.validate("01/01/2024").is_ok());
82 assert!(constraint.validate("31/12/2024").is_ok());
83 assert!(constraint.validate("2024-01-01").is_err());
84 }
85}