rs_firebase_admin_sdk/util/
serialize.rs

1use serde::de::{self, Visitor};
2use std::fmt;
3use time::OffsetDateTime;
4
5#[derive(Debug, Clone)]
6pub struct StrEpochMs {
7    dt: OffsetDateTime,
8}
9
10impl From<OffsetDateTime> for StrEpochMs {
11    fn from(dt: OffsetDateTime) -> Self {
12        Self { dt }
13    }
14}
15
16impl From<StrEpochMs> for OffsetDateTime {
17    fn from(value: StrEpochMs) -> Self {
18        value.dt
19    }
20}
21
22struct StrEpochMsVisitor;
23
24impl<'de> Visitor<'de> for StrEpochMsVisitor {
25    type Value = StrEpochMs;
26
27    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
28        formatter.write_str("a string containing count of miliseconds since UNIX epoch")
29    }
30
31    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
32    where
33        E: de::Error,
34    {
35        let unix_ts_ms: i128 = value.parse().map_err(|e| E::custom(format!("{e:?}")))?;
36
37        let off_dt = OffsetDateTime::from_unix_timestamp_nanos(unix_ts_ms * 1000000)
38            .map_err(|e| E::custom(format!("{e:?}")))?;
39
40        Ok(off_dt.into())
41    }
42}
43
44impl<'de> de::Deserialize<'de> for StrEpochMs {
45    fn deserialize<D>(deserializer: D) -> Result<StrEpochMs, D::Error>
46    where
47        D: de::Deserializer<'de>,
48    {
49        deserializer.deserialize_str(StrEpochMsVisitor)
50    }
51}
52
53#[derive(Debug, Clone)]
54pub struct StrEpochSec {
55    dt: OffsetDateTime,
56}
57
58impl From<OffsetDateTime> for StrEpochSec {
59    fn from(dt: OffsetDateTime) -> Self {
60        Self { dt }
61    }
62}
63
64impl From<StrEpochSec> for OffsetDateTime {
65    fn from(value: StrEpochSec) -> Self {
66        value.dt
67    }
68}
69
70struct StrEpochSecVisitor;
71
72impl<'de> Visitor<'de> for StrEpochSecVisitor {
73    type Value = StrEpochSec;
74
75    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
76        formatter.write_str("a string containing count of seconds since UNIX epoch")
77    }
78
79    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
80    where
81        E: de::Error,
82    {
83        let unix_ts: i64 = value.parse().map_err(|e| E::custom(format!("{e:?}")))?;
84
85        let off_dt = OffsetDateTime::from_unix_timestamp(unix_ts)
86            .map_err(|e| E::custom(format!("{e:?}")))?;
87
88        Ok(off_dt.into())
89    }
90}
91
92impl<'de> de::Deserialize<'de> for StrEpochSec {
93    fn deserialize<D>(deserializer: D) -> Result<StrEpochSec, D::Error>
94    where
95        D: de::Deserializer<'de>,
96    {
97        deserializer.deserialize_str(StrEpochSecVisitor)
98    }
99}
100
101#[derive(Debug, Clone)]
102pub struct I128EpochMs {
103    dt: OffsetDateTime,
104}
105
106impl From<OffsetDateTime> for I128EpochMs {
107    fn from(dt: OffsetDateTime) -> Self {
108        Self { dt }
109    }
110}
111
112impl From<I128EpochMs> for OffsetDateTime {
113    fn from(value: I128EpochMs) -> Self {
114        value.dt
115    }
116}
117
118struct I128EpochMsVisitor;
119
120impl<'de> Visitor<'de> for I128EpochMsVisitor {
121    type Value = I128EpochMs;
122
123    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
124        formatter.write_str("an integer containing count of miliseconds since UNIX epoch")
125    }
126
127    fn visit_i128<E>(self, value: i128) -> Result<Self::Value, E>
128    where
129        E: de::Error,
130    {
131        let off_dt = OffsetDateTime::from_unix_timestamp_nanos(value * 1000000)
132            .map_err(|e| E::custom(format!("{e:?}")))?;
133
134        Ok(off_dt.into())
135    }
136}
137
138impl<'de> de::Deserialize<'de> for I128EpochMs {
139    fn deserialize<D>(deserializer: D) -> Result<I128EpochMs, D::Error>
140    where
141        D: de::Deserializer<'de>,
142    {
143        deserializer.deserialize_i128(I128EpochMsVisitor)
144    }
145}