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 Into<Duration> for Seconds {
44 fn into(self) -> Duration {
45 let Seconds(secs) = self;
46 Duration::new(secs.trunc() as u64, (secs.fract() * 1.0e9) as u32)
47 }
48}
49
50struct SecondsVisitor;
51
52impl<'de> de::Visitor<'de> for SecondsVisitor {
53 type Value = Seconds;
54
55 fn expecting(
56 &self,
57 formatter: &mut fmt::Formatter,
58 ) -> fmt::Result {
59 formatter.write_str("a string value")
60 }
61 fn visit_f64<E>(
62 self,
63 value: f64,
64 ) -> Result<Seconds, E>
65 where
66 E: de::Error,
67 {
68 Ok(Seconds(value))
69 }
70}
71
72impl ser::Serialize for Seconds {
73 fn serialize<S>(
74 &self,
75 serializer: S,
76 ) -> Result<S::Ok, S::Error>
77 where
78 S: Serializer,
79 {
80 let Seconds(seconds) = self;
81 serializer.serialize_f64(*seconds)
82 }
83}
84
85impl<'de> de::Deserialize<'de> for Seconds {
86 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
87 where
88 D: de::Deserializer<'de>,
89 {
90 deserializer.deserialize_f64(SecondsVisitor)
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::Seconds;
97
98 #[test]
99 fn seconds_serialize() {
100 assert_eq!(
101 serde_json::to_string(&Seconds(1_545_136_342.711_932)).expect("failed to serialize"),
102 "1545136342.711932"
103 );
104 }
105
106 #[test]
107 fn seconds_deserialize() {
108 assert_eq!(
109 serde_json::from_slice::<Seconds>(b"1545136342.711932").expect("failed to serialize"),
110 Seconds(1_545_136_342.711_932)
111 );
112 }
113}