karbon_framework/validation/constraints/date/
date_time.rs1use crate::validation::constraints::{Constraint, ConstraintResult, ConstraintViolation};
2
3pub struct DateTime {
8 pub message: String,
9 pub format: String,
10}
11
12impl Default for DateTime {
13 fn default() -> Self {
14 Self {
15 message: "This value is not a valid datetime.".to_string(),
16 format: "%Y-%m-%d %H:%M:%S".to_string(),
17 }
18 }
19}
20
21impl DateTime {
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 pub fn iso8601() -> Self {
38 Self {
39 format: "%Y-%m-%dT%H:%M:%S".to_string(),
40 ..Self::default()
41 }
42 }
43}
44
45impl Constraint for DateTime {
46 fn validate(&self, value: &str) -> ConstraintResult {
47 if chrono::NaiveDateTime::parse_from_str(value, &self.format).is_err() {
48 return Err(ConstraintViolation::new(
49 self.name(),
50 &self.message,
51 value,
52 ));
53 }
54 Ok(())
55 }
56
57 fn name(&self) -> &'static str {
58 "DateTime"
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn test_valid_datetimes() {
68 let constraint = DateTime::new();
69 assert!(constraint.validate("2024-01-01 00:00:00").is_ok());
70 assert!(constraint.validate("2024-12-31 23:59:59").is_ok());
71 assert!(constraint.validate("2024-06-15 14:30:00").is_ok());
72 }
73
74 #[test]
75 fn test_invalid_datetimes() {
76 let constraint = DateTime::new();
77 assert!(constraint.validate("").is_err());
78 assert!(constraint.validate("2024-01-01").is_err()); assert!(constraint.validate("not-a-datetime").is_err());
80 assert!(constraint.validate("2024-01-01 25:00:00").is_err()); }
82
83 #[test]
84 fn test_iso8601_format() {
85 let constraint = DateTime::iso8601();
86 assert!(constraint.validate("2024-01-01T12:00:00").is_ok());
87 assert!(constraint.validate("2024-01-01 12:00:00").is_err());
88 }
89
90 #[test]
91 fn test_custom_format() {
92 let constraint = DateTime::new().with_format("%d/%m/%Y %H:%M");
93 assert!(constraint.validate("01/01/2024 12:00").is_ok());
94 assert!(constraint.validate("2024-01-01 12:00:00").is_err());
95 }
96}