1use chrono::{DateTime, FixedOffset, ParseResult, TimeZone};
3use serde::{self, Deserialize, Deserializer};
4
5const FORMAT: &str = "%Y-%m-%dT%H:%M:%S";
6const HOUR: i32 = 3600;
7
8pub struct Date {
9 pub year: u16,
10 pub month: u8,
11 pub day: u8,
12}
13
14impl Date {
15 pub fn new(year: u16, month: u8, day: u8) -> Self {
16 Date { year, month, day }
17 }
18}
19
20impl ToString for Date {
21 fn to_string(&self) -> String {
22 format!("{:04}-{:02}-{:02}", self.year, self.month, self.day)
23 }
24}
25
26fn string_time_to_date(time: &str) -> ParseResult<DateTime<FixedOffset>> {
27 FixedOffset::west(HOUR * 5).datetime_from_str(time, FORMAT)
28}
29
30pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<DateTime<FixedOffset>, D::Error>
31where
32 D: Deserializer<'de>,
33{
34 string_time_to_date(&String::deserialize(deserializer)?).map_err(serde::de::Error::custom)
35}
36
37pub(crate) fn deserialize_option<'de, D>(
38 deserializer: D,
39) -> Result<Option<DateTime<FixedOffset>>, D::Error>
40where
41 D: Deserializer<'de>,
42{
43 String::deserialize(deserializer).map(|s| string_time_to_date(&s).ok())
44}