1#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
14#[cfg_attr(feature = "schemars", schemars(transparent))]
15pub struct Timestamp(u64);
16
17impl Timestamp {
18 #[inline]
20 pub const fn from_nanos(nanos: u64) -> Self {
21 Self(nanos)
22 }
23
24 #[inline]
26 pub const fn as_nanos(&self) -> u64 {
27 self.0
28 }
29}
30
31#[cfg(feature = "std")]
32impl From<std::time::SystemTime> for Timestamp {
33 fn from(t: std::time::SystemTime) -> Self {
34 let nanos = t
35 .duration_since(std::time::UNIX_EPOCH)
36 .expect("system time before Unix epoch")
37 .as_nanos() as u64;
38 Self(nanos)
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 #[test]
47 fn round_trips_nanos() {
48 let ts = Timestamp::from_nanos(1_000_000_000);
49 assert_eq!(ts.as_nanos(), 1_000_000_000);
50 }
51
52 #[cfg(feature = "std")]
53 #[test]
54 fn from_system_time_at_epoch_is_zero() {
55 let ts = Timestamp::from(std::time::SystemTime::UNIX_EPOCH);
56 assert_eq!(ts.as_nanos(), 0);
57 }
58}