Skip to main content

ave_identity/
timestamp.rs

1//! Timestamp type for cryptographic signatures
2//!
3//! This module provides a simple timestamp type that can be used in signatures
4//! to record when a signature was created.
5
6use borsh::{BorshDeserialize, BorshSerialize};
7use serde::{Deserialize, Serialize};
8use time::OffsetDateTime;
9
10/// A timestamp representing nanoseconds since UNIX epoch
11#[derive(
12    Debug,
13    Clone,
14    Copy,
15    PartialEq,
16    Eq,
17    PartialOrd,
18    Ord,
19    Hash,
20    Serialize,
21    Deserialize,
22    BorshSerialize,
23    BorshDeserialize,
24)]
25pub struct TimeStamp(u64);
26
27impl TimeStamp {
28    /// Returns a new `TimeStamp` representing the current time
29    pub fn now() -> Self {
30        Self(OffsetDateTime::now_utc().unix_timestamp_nanos() as u64)
31    }
32
33    /// Create a timestamp from nanoseconds since UNIX epoch
34    pub fn from_nanos(nanos: u64) -> Self {
35        TimeStamp(nanos)
36    }
37
38    /// Get the timestamp as nanoseconds since UNIX epoch
39    pub fn as_nanos(&self) -> u64 {
40        self.0
41    }
42}
43
44impl std::fmt::Display for TimeStamp {
45    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46        write!(f, "{}", self.0)
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn test_timestamp_now() {
56        let ts1 = TimeStamp::now();
57        let ts2 = TimeStamp::now();
58
59        // Second timestamp should be >= first
60        assert!(ts2 >= ts1);
61    }
62
63    #[test]
64    fn test_timestamp_from_nanos() {
65        let ts = TimeStamp::from_nanos(1234567890123456789);
66        assert_eq!(ts.as_nanos(), 1234567890123456789);
67    }
68
69    #[test]
70    fn test_timestamp_ordering() {
71        let ts1 = TimeStamp::from_nanos(1000);
72        let ts2 = TimeStamp::from_nanos(2000);
73
74        assert!(ts1 < ts2);
75        assert!(ts2 > ts1);
76    }
77
78    #[test]
79    fn test_timestamp_serde() {
80        let ts = TimeStamp::now();
81        let json = serde_json::to_string(&ts).unwrap();
82        let deserialized: TimeStamp = serde_json::from_str(&json).unwrap();
83        assert_eq!(ts, deserialized);
84    }
85
86    #[test]
87    fn test_timestamp_borsh() {
88        let ts = TimeStamp::now();
89        let bytes = borsh::to_vec(&ts).unwrap();
90        let deserialized: TimeStamp = borsh::from_slice(&bytes).unwrap();
91        assert_eq!(ts, deserialized);
92    }
93}