tanzim_validate/
datetime.rs1use crate::error::{Error, ErrorKind};
2use crate::{Meta, Validator};
3use tanzim_value::{Value, ValueType};
4
5fn as_str(value: &mut Value) -> Result<&str, Error> {
7 match value {
8 Value::String(text) => Ok(text),
9 other => Err(Error::new(ErrorKind::Type {
10 expected: ValueType::String,
11 found: other.type_name(),
12 })),
13 }
14}
15
16#[derive(Debug, Clone, Default)]
18pub struct DateTime {
19 meta: Meta,
20}
21
22impl DateTime {
23 pub fn new() -> Self {
24 Self {
25 meta: Meta::default(),
26 }
27 }
28
29 pub fn with_meta(mut self, meta: Meta) -> Self {
31 self.meta = meta;
32 self
33 }
34}
35
36crate::impl_meta_methods!(DateTime);
37
38impl Validator for DateTime {
39 fn meta(&self) -> &Meta {
40 &self.meta
41 }
42
43 fn meta_mut(&mut self) -> &mut Meta {
44 &mut self.meta
45 }
46
47 fn check(&self, value: &mut Value) -> Result<(), Error> {
48 let text = as_str(value)?;
49 match text.parse::<jiff::Timestamp>() {
50 Ok(_) => Ok(()),
51 Err(_) => Err(Error::new(ErrorKind::Format {
52 expected: "RFC 3339 datetime",
53 })),
54 }
55 }
56}
57
58#[derive(Debug, Clone, Default)]
60pub struct Date {
61 meta: Meta,
62}
63
64impl Date {
65 pub fn new() -> Self {
66 Self {
67 meta: Meta::default(),
68 }
69 }
70
71 pub fn with_meta(mut self, meta: Meta) -> Self {
73 self.meta = meta;
74 self
75 }
76}
77
78crate::impl_meta_methods!(Date);
79
80impl Validator for Date {
81 fn meta(&self) -> &Meta {
82 &self.meta
83 }
84
85 fn meta_mut(&mut self) -> &mut Meta {
86 &mut self.meta
87 }
88
89 fn check(&self, value: &mut Value) -> Result<(), Error> {
90 let text = as_str(value)?;
91 match text.parse::<jiff::civil::Date>() {
92 Ok(_) => Ok(()),
93 Err(_) => Err(Error::new(ErrorKind::Format { expected: "date" })),
94 }
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn datetime_accepts_rfc3339() {
104 assert!(
105 DateTime::new()
106 .validate(&mut Value::String("2024-01-02T15:04:05Z".into()))
107 .is_ok()
108 );
109 assert!(
110 DateTime::new()
111 .validate(&mut Value::String("yesterday".into()))
112 .is_err()
113 );
114 }
115
116 #[test]
117 fn date_accepts_calendar_date() {
118 assert!(
119 Date::new()
120 .validate(&mut Value::String("2024-01-02".into()))
121 .is_ok()
122 );
123 assert!(
124 Date::new()
125 .validate(&mut Value::String("2024-13-99".into()))
126 .is_err()
127 );
128 }
129}