binance_openapi/
datetimerfc3339.rs1use 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 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}