libtad_models/time/
datetime.rs1use serde::{Deserialize, Deserializer, Serialize, Serializer};
2
3#[derive(Debug, Default, Clone, Copy, PartialEq, Deserialize)]
4#[serde(default)]
5pub struct DateTime {
7 pub year: i32,
9
10 pub month: i32,
12
13 pub day: i32,
15
16 pub hour: i32,
18
19 pub minute: i32,
21
22 pub second: i32,
24}
25
26impl Serialize for DateTime {
27 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
28 where
29 S: Serializer,
30 {
31 serializer.serialize_str(&self.to_string())
32 }
33}
34
35impl DateTime {
36 pub(crate) fn option_deserialize_from_str<'a, D>(
37 deserializer: D,
38 ) -> Result<Option<Self>, D::Error>
39 where
40 D: Deserializer<'a>,
41 {
42 let s: Option<String> = Option::deserialize(deserializer)?;
43 if let Some(inner) = s {
44 Ok(Some(DateTime::from(&inner)))
45 } else {
46 Ok(None)
47 }
48 }
49
50 pub(crate) fn deserialize_from_str<'a, D>(deserializer: D) -> Result<Self, D::Error>
51 where
52 D: Deserializer<'a>,
53 {
54 let s = String::deserialize(deserializer)?;
55
56 Ok(DateTime::from(&s))
57 }
58}
59
60impl std::fmt::Display for DateTime {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 write!(
63 f,
64 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}",
65 self.year, self.month, self.day, self.hour, self.minute, self.second
66 )
67 }
68}
69
70impl<A: AsRef<str>> From<A> for DateTime {
71 fn from(s: A) -> Self {
72 fn alt(s: &str) -> (&str, &str) {
73 if let Some(d) = s.split_once('-') {
74 return d;
75 }
76
77 if let Some(m) = s.split_once('T') {
78 return m;
79 }
80
81 if let Some(t) = s.split_once(':') {
82 return t;
83 }
84
85 (s, "")
86 }
87
88 let (year, rest) = alt(s.as_ref());
89 let (month, rest) = alt(rest);
90 let (day, rest) = alt(rest);
91 let (hour, rest) = alt(rest);
92 let (minute, rest) = alt(rest);
93 let (second, _) = alt(rest);
94
95 Self {
96 year: year.parse().unwrap_or_default(),
97 month: month.parse().unwrap_or_default(),
98 day: day.parse().unwrap_or_default(),
99 hour: hour.parse().unwrap_or_default(),
100 minute: minute.parse().unwrap_or_default(),
101 second: second.parse().unwrap_or_default(),
102 }
103 }
104}
105
106#[test]
107fn parse_datetime() {
108 let datetime_str = "2021-04-04T16:42:21";
109
110 let datetime = DateTime::from(datetime_str.to_string());
111
112 assert!(datetime.year == 2021);
113 assert!(datetime.month == 4);
114 assert!(datetime.day == 4);
115 assert!(datetime.hour == 16);
116 assert!(datetime.minute == 42);
117 assert!(datetime.second == 21);
118}
119
120#[test]
121fn parse_date_only() {
122 let datetime_str = "2021-04-04";
123
124 let datetime = DateTime::from(datetime_str.to_string());
125
126 assert!(datetime.year == 2021);
127 assert!(datetime.month == 4);
128 assert!(datetime.day == 4);
129 assert!(datetime.hour == 0);
130 assert!(datetime.minute == 0);
131 assert!(datetime.second == 0);
132}