1#![allow(dead_code)]
2
3use std::str::FromStr;
4
5use serde::{Deserialize, Deserializer, Serializer, de::Error as _, ser::Error as _};
6use time::{Date, OffsetDateTime};
7
8pub(crate) mod date_opt {
9 use super::*;
10
11 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<Date>, D::Error>
12 where
13 D: Deserializer<'de>,
14 {
15 let value = String::deserialize(deserializer)?;
16 if !value.is_empty() {
17 let datetime = Date::parse(
18 &value,
19 time::macros::format_description!("[year]-[month]-[day]"),
20 )
21 .map_err(D::Error::custom)?;
22 Ok(Some(datetime))
23 } else {
24 Ok(None)
25 }
26 }
27
28 pub(crate) fn serialize<S>(datetime: &Option<Date>, serializer: S) -> Result<S::Ok, S::Error>
29 where
30 S: Serializer,
31 {
32 match datetime {
33 Some(date) => serializer.serialize_str(
34 &date
35 .format(time::macros::format_description!("[year]-[month]-[day]"))
36 .unwrap(),
37 ),
38 None => serializer.serialize_none(),
39 }
40 }
41}
42
43pub(crate) mod timestamp {
44 use super::*;
45
46 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<OffsetDateTime, D::Error>
47 where
48 D: Deserializer<'de>,
49 {
50 let value = String::deserialize(deserializer)?;
51 let value = value.parse::<i64>().map_err(D::Error::custom)?;
52 OffsetDateTime::from_unix_timestamp(value).map_err(D::Error::custom)
53 }
54
55 pub(crate) fn serialize<S>(datetime: &OffsetDateTime, serializer: S) -> Result<S::Ok, S::Error>
56 where
57 S: Serializer,
58 {
59 serializer.collect_str(&datetime.unix_timestamp())
60 }
61}
62
63pub(crate) mod timestamp_opt {
64 use super::*;
65
66 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<OffsetDateTime>, D::Error>
67 where
68 D: Deserializer<'de>,
69 {
70 let Some(value) = <Option<String>>::deserialize(deserializer)? else {
71 return Ok(None);
72 };
73 if value.is_empty() {
74 return Ok(None);
75 }
76
77 let value = value.parse::<i64>().map_err(D::Error::custom)?;
78 if value != 0 {
79 let datetime = OffsetDateTime::from_unix_timestamp(value).map_err(D::Error::custom)?;
80 Ok(Some(datetime))
81 } else {
82 Ok(None)
83 }
84 }
85
86 pub(crate) fn serialize<S>(
87 datetime: &Option<OffsetDateTime>,
88 serializer: S,
89 ) -> Result<S::Ok, S::Error>
90 where
91 S: Serializer,
92 {
93 match datetime {
94 Some(datetime) => serializer.collect_str(&datetime.unix_timestamp()),
95 None => serializer.serialize_none(),
96 }
97 }
98}
99
100pub(crate) mod rfc3339_opt {
101 use super::*;
102
103 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<OffsetDateTime>, D::Error>
104 where
105 D: Deserializer<'de>,
106 {
107 let Some(value) = <Option<String>>::deserialize(deserializer)? else {
108 return Ok(None);
109 };
110 if value.is_empty() {
111 return Ok(None);
112 }
113 let datetime =
114 OffsetDateTime::parse(&value, &time::format_description::well_known::Rfc3339)
115 .map_err(D::Error::custom)?;
116 Ok(Some(datetime))
117 }
118
119 pub(crate) fn serialize<S>(
120 datetime: &Option<OffsetDateTime>,
121 serializer: S,
122 ) -> Result<S::Ok, S::Error>
123 where
124 S: Serializer,
125 {
126 match datetime {
127 Some(datetime) => serializer.collect_str(
128 &datetime
129 .format(&time::format_description::well_known::Rfc3339)
130 .map_err(S::Error::custom)?,
131 ),
132 None => serializer.serialize_none(),
133 }
134 }
135}
136
137pub(crate) mod risk_level {
138 use super::*;
139
140 pub(crate) fn serialize<S>(value: &i32, serializer: S) -> Result<S::Ok, S::Error>
141 where
142 S: Serializer,
143 {
144 serializer.collect_str(value)
145 }
146
147 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<i32, D::Error>
148 where
149 D: Deserializer<'de>,
150 {
151 let value = String::deserialize(deserializer)?;
152 if !value.is_empty() {
153 Ok(value
154 .parse::<i32>()
155 .map_err(|err| D::Error::custom(err.to_string()))?)
156 } else {
157 Ok(0)
158 }
159 }
160}
161
162pub(crate) mod decimal_empty_is_0 {
163 use rust_decimal::Decimal;
164
165 use super::*;
166
167 pub(crate) fn serialize<S>(value: &Decimal, serializer: S) -> Result<S::Ok, S::Error>
168 where
169 S: Serializer,
170 {
171 serializer.collect_str(&value)
172 }
173
174 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Decimal, D::Error>
175 where
176 D: Deserializer<'de>,
177 {
178 let value = String::deserialize(deserializer)?;
179 if !value.is_empty() {
180 let n = value.parse::<Decimal>().map_err(D::Error::custom)?;
181 Ok(n)
182 } else {
183 Ok(Decimal::ZERO)
184 }
185 }
186}
187
188pub(crate) mod decimal_opt_empty_is_none {
189 use rust_decimal::Decimal;
190
191 use super::*;
192
193 pub(crate) fn serialize<S>(value: &Option<Decimal>, serializer: S) -> Result<S::Ok, S::Error>
194 where
195 S: Serializer,
196 {
197 match value {
198 Some(value) => serializer.collect_str(&value),
199 _ => serializer.serialize_none(),
200 }
201 }
202
203 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<Decimal>, D::Error>
204 where
205 D: Deserializer<'de>,
206 {
207 let value = String::deserialize(deserializer)?;
208 if !value.is_empty() {
209 let n = value.parse::<Decimal>().map_err(D::Error::custom)?;
210 Ok(Some(n))
211 } else {
212 Ok(None)
213 }
214 }
215}
216
217pub(crate) mod decimal_opt_0_is_none {
218 use rust_decimal::Decimal;
219
220 use super::*;
221
222 pub(crate) fn serialize<S>(value: &Option<Decimal>, serializer: S) -> Result<S::Ok, S::Error>
223 where
224 S: Serializer,
225 {
226 match value {
227 Some(value) => serializer.collect_str(&value),
228 _ => serializer.serialize_none(),
229 }
230 }
231
232 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<Decimal>, D::Error>
233 where
234 D: Deserializer<'de>,
235 {
236 let value = String::deserialize(deserializer)?;
237 let n = value.parse::<Decimal>().map_err(D::Error::custom)?;
238 if !n.is_zero() { Ok(Some(n)) } else { Ok(None) }
239 }
240}
241
242pub(crate) mod trigger_status {
243 use super::*;
244 use crate::trade::TriggerStatus;
245
246 pub(crate) fn serialize<S>(
247 value: &Option<TriggerStatus>,
248 serializer: S,
249 ) -> Result<S::Ok, S::Error>
250 where
251 S: Serializer,
252 {
253 match value {
254 Some(value) => serializer.collect_str(value),
255 None => serializer.serialize_none(),
256 }
257 }
258
259 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<TriggerStatus>, D::Error>
260 where
261 D: Deserializer<'de>,
262 {
263 let value = String::deserialize(deserializer)?;
264 match value.as_str() {
265 "NOT_USED" => Ok(None),
266 _ => Ok(Some(
267 TriggerStatus::from_str(value.as_str()).unwrap_or_default(),
268 )),
269 }
270 }
271}
272
273pub(crate) mod outside_rth {
274 use super::*;
275 use crate::trade::OutsideRTH;
276
277 pub(crate) fn serialize<S>(value: &Option<OutsideRTH>, serializer: S) -> Result<S::Ok, S::Error>
278 where
279 S: Serializer,
280 {
281 match value {
282 Some(value) => serializer.collect_str(value),
283 None => serializer.serialize_none(),
284 }
285 }
286
287 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<OutsideRTH>, D::Error>
288 where
289 D: Deserializer<'de>,
290 {
291 let value = String::deserialize(deserializer)?;
292 match value.as_str() {
293 "UnknownOutsideRth" => Ok(None),
294 _ => Ok(Some(
295 OutsideRTH::from_str(value.as_str()).unwrap_or_default(),
296 )),
297 }
298 }
299}
300
301pub(crate) mod symbol_opt {
302 use super::*;
303
304 pub(crate) fn serialize<S>(value: &Option<String>, serializer: S) -> Result<S::Ok, S::Error>
305 where
306 S: Serializer,
307 {
308 match value {
309 Some(value) => serializer.serialize_str(value),
310 None => serializer.serialize_none(),
311 }
312 }
313
314 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
315 where
316 D: Deserializer<'de>,
317 {
318 match <Option<String>>::deserialize(deserializer)? {
319 Some(value) if value.is_empty() => Ok(None),
320 Some(value) => Ok(Some(value)),
321 _ => Ok(None),
322 }
323 }
324}
325
326pub(crate) mod int64_str {
327 use super::*;
328
329 pub(crate) fn serialize<S>(value: &i64, serializer: S) -> Result<S::Ok, S::Error>
330 where
331 S: Serializer,
332 {
333 serializer.collect_str(value)
334 }
335
336 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<i64, D::Error>
337 where
338 D: Deserializer<'de>,
339 {
340 let value = String::deserialize(deserializer)?;
341 Ok(value.parse::<i64>().unwrap_or_default())
342 }
343}
344
345pub(crate) mod int64_str_empty_is_none {
346 use super::*;
347
348 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<i64>, D::Error>
349 where
350 D: Deserializer<'de>,
351 {
352 let value = String::deserialize(deserializer)?;
353 if !value.is_empty() {
354 Ok(Some(
355 value
356 .parse::<i64>()
357 .map_err(|err| D::Error::custom(err.to_string()))?,
358 ))
359 } else {
360 Ok(None)
361 }
362 }
363}