1use serde::{de, ser, Serializer};
2use std::{
3 fmt,
4 time::{Duration, SystemTime, UNIX_EPOCH},
5};
6
7#[derive(Debug, PartialEq)]
14pub struct Seconds(pub(crate) f64);
15
16impl Seconds {
17 pub fn now() -> Self {
19 SystemTime::now()
20 .duration_since(UNIX_EPOCH)
21 .unwrap_or_default()
22 .into()
23 }
24
25 pub fn trunc(&self) -> u64 {
27 self.0.trunc() as u64
28 }
29}
30
31impl Default for Seconds {
32 fn default() -> Self {
33 Seconds::now()
34 }
35}
36
37impl From<Duration> for Seconds {
38 fn from(d: Duration) -> Self {
39 Seconds(d.as_secs() as f64 + (f64::from(d.subsec_nanos()) / 1.0e9))
40 }
41}
42
43impl From<Seconds> for Duration {
44 fn from(s: Seconds) -> Self {
45 Duration::new(s.0.trunc() as u64, (s.0.fract() * 1.0e9) as u32)
46 }
47}
48
49struct SecondsVisitor;
50
51impl<'de> de::Visitor<'de> for SecondsVisitor {
52 type Value = Seconds;
53
54 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
55 formatter.write_str("a string value")
56 }
57 fn visit_f64<E>(self, value: f64) -> Result<Seconds, E>
58 where
59 E: de::Error,
60 {
61 Ok(Seconds(value))
62 }
63}
64
65impl ser::Serialize for Seconds {
66 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
67 where
68 S: Serializer,
69 {
70 let Seconds(seconds) = self;
71 serializer.serialize_f64(*seconds)
72 }
73}
74
75impl<'de> de::Deserialize<'de> for Seconds {
76 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
77 where
78 D: de::Deserializer<'de>,
79 {
80 deserializer.deserialize_f64(SecondsVisitor)
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::Seconds;
87
88 #[test]
89 fn seconds_serialize() {
90 assert_eq!(
91 serde_json::to_string(&Seconds(1_545_136_342.711_932)).expect("failed to serialize"),
92 "1545136342.711932"
93 );
94 }
95
96 #[test]
97 fn seconds_deserialize() {
98 assert_eq!(
99 serde_json::from_slice::<Seconds>(b"1545136342.711932").expect("failed to serialize"),
100 Seconds(1_545_136_342.711_932)
101 );
102 }
103}