r402_core/wire/
timestamp.rs1use std::fmt::{self, Display, Formatter};
4use std::ops::Add;
5use std::time::SystemTime;
6
7use serde::{Deserialize, Deserializer, Serialize, Serializer};
8
9#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Ord, Eq, Hash)]
27pub struct UnixTimestamp(u64);
28
29impl UnixTimestamp {
30 #[must_use]
32 pub const fn from_secs(secs: u64) -> Self {
33 Self(secs)
34 }
35
36 #[must_use]
40 pub fn now() -> Self {
41 let secs = SystemTime::now()
42 .duration_since(SystemTime::UNIX_EPOCH)
43 .map(|d| d.as_secs())
44 .unwrap_or_default();
45 Self(secs)
46 }
47
48 #[must_use]
50 pub const fn as_secs(self) -> u64 {
51 self.0
52 }
53}
54
55impl Display for UnixTimestamp {
56 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
57 Display::fmt(&self.0, f)
58 }
59}
60
61impl Add<u64> for UnixTimestamp {
62 type Output = Self;
63 fn add(self, rhs: u64) -> Self::Output {
64 Self(self.0.saturating_add(rhs))
65 }
66}
67
68impl Serialize for UnixTimestamp {
69 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
70 serializer.collect_str(&self.0)
71 }
72}
73
74impl<'de> Deserialize<'de> for UnixTimestamp {
75 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
76 struct Visitor;
77
78 impl serde::de::Visitor<'_> for Visitor {
79 type Value = UnixTimestamp;
80
81 fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result {
82 f.write_str("a non-negative integer or its string representation")
83 }
84
85 fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<Self::Value, E> {
86 Ok(UnixTimestamp(v))
87 }
88
89 fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
90 v.parse::<u64>()
91 .map(UnixTimestamp)
92 .map_err(|_| E::custom("expected non-negative integer"))
93 }
94 }
95
96 deserializer.deserialize_any(Visitor)
97 }
98}