binance_openapi/
datetimerfc3339.rs

1use std::str::FromStr;
2use serde::Deserialize;
3use serde::Serialize;
4
5
6#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
7pub struct DateRfc3339(pub(crate) chrono::Date<chrono::Utc>);
8
9impl DateRfc3339 {
10    pub fn now() -> Self {
11        Self(chrono::Utc::today())
12    }
13
14    pub fn from_naive(naive: chrono::NaiveDate) -> Self {
15        Self(chrono::Date::from_utc(naive, chrono::Utc))
16    }
17}
18
19impl FromStr for DateRfc3339 {
20    type Err = chrono::ParseError;
21    fn from_str(s: &str) -> Result<Self, Self::Err> {
22        let value = chrono::NaiveDate::parse_from_str(s, "%Y-%m-%d")
23            .or_else(|_| chrono::NaiveDate::parse_from_str(s, "%d.%m.%Y"))
24            .or_else(|_e| {
25                let millis = i64::from_str(s).map_err(|_| _e)?;
26                chrono::NaiveDateTime::from_timestamp_millis(millis)
27                    .map(|dt| dt.date())
28                    .ok_or(_e)
29            })?;
30        Ok(Self(chrono::Date::from_utc(value, chrono::Utc)))
31    }
32}
33
34impl ToString for DateRfc3339 {
35    fn to_string(&self) -> String {
36        let v = self.0.format("%d.%m.%Y").to_string();
37        v
38    }
39}
40
41impl<'de> Deserialize<'de> for DateRfc3339 {
42    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
43    where
44        D: serde::Deserializer<'de>,
45    {
46        deserializer.deserialize_str(DateVisitorRfc3339)
47    }
48}
49
50impl Serialize for DateRfc3339 {
51    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
52    where
53        S: serde::Serializer,
54    {
55        let v = self.to_string();
56        serializer.serialize_str(v.as_str())
57    }
58}
59
60#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
61pub struct DateTimeRfc3339(pub chrono::DateTime<chrono::Utc>);
62
63impl DateTimeRfc3339 {
64    pub fn now() -> Self {
65        Self(chrono::Utc::now())
66    }
67
68    pub fn from_naive(naive: chrono::NaiveDateTime) -> Self {
69        Self(chrono::DateTime::from_utc(naive, chrono::Utc))
70    }
71
72    pub fn from_naive_date(naive: chrono::NaiveDate) -> Self {
73        let naive = naive
74            .and_time(chrono::NaiveTime::from_num_seconds_from_midnight_opt(100000, 0).unwrap());
75        Self(chrono::DateTime::from_utc(naive, chrono::Utc))
76    }
77}
78
79impl FromStr for DateTimeRfc3339 {
80    type Err = chrono::ParseError;
81    fn from_str(s: &str) -> Result<Self, Self::Err> {
82        let value = chrono::DateTime::parse_from_rfc3339(s)
83            .map(|dt| dt.with_timezone(&chrono::Utc))
84            .or_else(|_e| {
85                let millis = i64::from_str(s).map_err(|_| _e)?;
86                let naive =
87                    chrono::naive::NaiveDateTime::from_timestamp_millis(millis).ok_or(_e)?;
88                Ok(chrono::DateTime::from_local(naive, chrono::Utc))
89            })?;
90        Ok(Self(value))
91    }
92}
93
94impl ToString for DateTimeRfc3339 {
95    fn to_string(&self) -> String {
96        // let v = self.0.to_rfc3339(); // wishful thinking
97
98        self.0.timestamp_millis().to_string()
99    }
100}
101
102impl<'de> Deserialize<'de> for DateTimeRfc3339 {
103    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
104    where
105        D: serde::Deserializer<'de>,
106    {
107        deserializer.deserialize_str(DateTimeVisitorRfc3339)
108    }
109}
110
111impl Serialize for DateTimeRfc3339 {
112    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
113    where
114        S: serde::Serializer,
115    {
116        let v = self.to_string();
117        serializer.serialize_str(v.as_str())
118    }
119}
120
121#[derive(Debug, Clone, Copy, Hash)]
122struct DateTimeVisitorRfc3339;
123
124impl<'de> serde::de::Visitor<'de> for DateTimeVisitorRfc3339 {
125    type Value = DateTimeRfc3339;
126
127    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
128        write!(
129            formatter,
130            "a string containing an rfc33339 compliant timestamp"
131        )
132    }
133
134    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
135    where
136        E: serde::de::Error,
137    {
138        Self::Value::from_str(s).map_err(serde::de::Error::custom)
139    }
140
141    fn visit_string<E>(self, s: String) -> Result<Self::Value, E>
142    where
143        E: serde::de::Error,
144    {
145        self.visit_str::<E>(s.as_str())
146    }
147}
148
149#[derive(Debug, Clone, Copy, Hash)]
150struct DateVisitorRfc3339;
151
152impl<'de> serde::de::Visitor<'de> for DateVisitorRfc3339 {
153    type Value = DateRfc3339;
154
155    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
156        write!(
157            formatter,
158            "a string containing an rfc33339 compliant timestamp"
159        )
160    }
161
162    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
163    where
164        E: serde::de::Error,
165    {
166        Self::Value::from_str(s).map_err(serde::de::Error::custom)
167    }
168
169    fn visit_string<E>(self, s: String) -> Result<Self::Value, E>
170    where
171        E: serde::de::Error,
172    {
173        self.visit_str::<E>(s.as_str())
174    }
175}