openlimits_exchange/
shared.rs

1//! This module cointains some auxiliar functions that are used in the openlimits-exchange module
2
3pub type Result<T> = std::result::Result<T, crate::errors::OpenLimitsError>;
4
5pub mod string_to_decimal {
6    use std::fmt;
7
8    use rust_decimal::prelude::*;
9    use serde::{de, Deserialize, Deserializer, Serializer};
10
11    pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
12        where
13            T: fmt::Display,
14            S: Serializer,
15    {
16        serializer.collect_str(value)
17    }
18
19    pub fn deserialize<'de, D>(deserializer: D) -> Result<Decimal, D::Error>
20        where
21            D: Deserializer<'de>,
22    {
23        #[derive(Deserialize)]
24        #[serde(untagged)]
25        enum StringToDecimal {
26            String(String),
27        }
28
29        let StringToDecimal::String(s) = StringToDecimal::deserialize(deserializer)?;
30        Decimal::from_str(&s).map_err(de::Error::custom)
31    }
32}
33
34pub mod string_to_opt_decimal {
35    use rust_decimal::prelude::*;
36    use serde::{Deserialize, Deserializer, Serializer};
37
38    pub fn serialize<S>(value: &Option<Decimal>, serializer: S) -> Result<S::Ok, S::Error>
39        where
40            S: Serializer,
41    {
42        if let Some(value) = value {
43            return serializer.collect_str(&value);
44        }
45        serializer.serialize_none()
46    }
47
48    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Decimal>, D::Error>
49        where
50            D: Deserializer<'de>,
51    {
52        #[derive(Deserialize)]
53        #[serde(untagged)]
54        enum StringToOptDecimal {
55            String(Option<String>),
56        }
57        let StringToOptDecimal::String(s) = StringToOptDecimal::deserialize(deserializer)?;
58        if let Some(s) = s {
59            return Decimal::from_str(&s).map(Some).or(Ok(None));
60        }
61        Ok(None)
62    }
63}
64
65pub mod naive_datetime_from_string {
66    use chrono::naive::NaiveDateTime;
67    use serde::{Deserialize, Deserializer, Serializer};
68    use std::fmt;
69
70    pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
71        where
72            T: fmt::Display,
73            S: Serializer,
74    {
75        serializer.collect_str(value)
76    }
77
78    pub fn deserialize<'de, D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
79        where
80            D: Deserializer<'de>,
81    {
82        #[derive(Deserialize)]
83        #[serde(untagged)]
84        enum DatetimeFromString {
85            String(String),
86        }
87
88        let DatetimeFromString::String(s) = DatetimeFromString::deserialize(deserializer)?;
89        let a = NaiveDateTime::parse_from_str(&s, "%Y-%m-%dT%H:%M:%S.%fZ");
90        match a {
91            Ok(t) => Ok(t),
92            Err(_e) => NaiveDateTime::parse_from_str(&s, "%Y-%m-%dT%H:%M:%SZ")
93                .map_err(serde::de::Error::custom),
94        }
95    }
96}
97
98pub mod opt_naive_datetime_from_string {
99    use chrono::naive::NaiveDateTime;
100    use serde::{Deserialize, Deserializer, Serializer};
101
102    pub fn serialize<S>(value: &Option<NaiveDateTime>, serializer: S) -> Result<S::Ok, S::Error>
103        where
104            S: Serializer,
105    {
106        if let Some(value) = value {
107            return serializer.collect_str(&value);
108        }
109        serializer.serialize_none()
110    }
111
112    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<NaiveDateTime>, D::Error>
113        where
114            D: Deserializer<'de>,
115    {
116        #[derive(Deserialize)]
117        #[serde(untagged)]
118        enum OptDatetimeFromString {
119            String(Option<String>),
120        }
121
122        let OptDatetimeFromString::String(s) = OptDatetimeFromString::deserialize(deserializer)?;
123        if let Some(s) = s {
124            return NaiveDateTime::parse_from_str(&s, "%Y-%m-%dT%H:%M:%S.%fZ")
125                .map(Some)
126                .or(Ok(None));
127        }
128        Ok(None)
129    }
130}
131
132pub fn timestamp_to_naive_datetime(timestamp: u64) -> chrono::naive::NaiveDateTime {
133    let seconds = (timestamp / 1000) as i64;
134    let nanos = ((timestamp % 1000) * 1_000_000) as u32;
135
136    chrono::NaiveDateTime::from_timestamp(seconds, nanos)
137}
138
139pub fn timestamp_to_utc_datetime(timestamp: u64) -> chrono::DateTime<chrono::Utc> {
140    let d = timestamp_to_naive_datetime(timestamp);
141    chrono::DateTime::<chrono::Utc>::from_utc(d, chrono::Utc)
142}