Skip to main content

bma_ts/
convert.rs

1use std::str::FromStr;
2use std::time::Duration;
3
4use crate::{Error, Monotonic, Timestamp};
5
6#[cfg(feature = "chrono")]
7impl FromStr for Timestamp {
8    type Err = Error;
9    fn from_str(s: &str) -> Result<Self, Self::Err> {
10        #[cfg(not(feature = "as-float-secs"))]
11        if let Ok(v) = s.parse::<u64>() {
12            return Ok(v.into());
13        }
14        #[cfg(feature = "as-float-secs")]
15        if let Ok(v) = s.parse::<f64>() {
16            return Ok(v.into());
17        }
18        dateparser::parse(s)
19            .map_err(|e| Error::Parse(e.to_string()))?
20            .try_into()
21    }
22}
23
24#[cfg(not(feature = "chrono"))]
25impl FromStr for Timestamp {
26    type Err = Error;
27    #[cfg(not(feature = "as-float-secs"))]
28    fn from_str(s: &str) -> Result<Self, Self::Err> {
29        Ok(s.parse::<u64>()?.into())
30    }
31    #[cfg(feature = "as-float-secs")]
32    fn from_str(s: &str) -> Result<Self, Self::Err> {
33        Ok(s.parse::<f64>()?.into())
34    }
35}
36
37impl FromStr for Monotonic {
38    type Err = Error;
39    fn from_str(s: &str) -> Result<Self, Self::Err> {
40        Ok(s.parse::<u64>()?.into())
41    }
42}
43
44macro_rules! impl_common_convert {
45    ($t: ty) => {
46        // Duration
47        //
48        impl From<Duration> for $t {
49            fn from(value: Duration) -> Self {
50                Self(value)
51            }
52        }
53
54        impl From<$t> for Duration {
55            fn from(value: $t) -> Self {
56                value.0
57            }
58        }
59
60        // i64
61
62        impl TryFrom<i64> for $t {
63            type Error = Error;
64            fn try_from(value: i64) -> Result<Self, Self::Error> {
65                Ok(Self::from_nanos(u64::try_from(value)?))
66            }
67        }
68
69        impl TryFrom<$t> for i64 {
70            type Error = Error;
71            fn try_from(value: $t) -> Result<Self, Self::Error> {
72                value.as_nanos().try_into().map_err(Into::into)
73            }
74        }
75
76        // u64
77
78        impl From<u64> for $t {
79            fn from(value: u64) -> Self {
80                Self::from_nanos(value)
81            }
82        }
83
84        impl TryFrom<$t> for u64 {
85            type Error = Error;
86            fn try_from(value: $t) -> Result<Self, Error> {
87                value.as_nanos().try_into().map_err(Into::into)
88            }
89        }
90
91        // u128
92
93        impl From<$t> for u128 {
94            fn from(value: $t) -> Self {
95                value.as_nanos()
96            }
97        }
98
99        impl TryFrom<u128> for $t {
100            type Error = Error;
101            fn try_from(value: u128) -> Result<Self, Self::Error> {
102                Ok(<$t>::from_nanos(value.try_into()?))
103            }
104        }
105
106        // f32
107
108        impl From<f32> for $t {
109            fn from(value: f32) -> Self {
110                Self::from_secs_f32(value)
111            }
112        }
113
114        impl From<$t> for f32 {
115            fn from(value: $t) -> Self {
116                value.as_secs_f32()
117            }
118        }
119
120        // f64
121
122        impl From<f64> for $t {
123            fn from(value: f64) -> Self {
124                Self::from_secs_f64(value)
125            }
126        }
127
128        impl From<$t> for f64 {
129            fn from(value: $t) -> Self {
130                value.as_secs_f64()
131            }
132        }
133    };
134}
135
136impl_common_convert!(Timestamp);
137impl_common_convert!(Monotonic);