casper_client/types/
timestamp.rs

1use std::{
2    fmt::{self, Display, Formatter},
3    str::FromStr,
4    time::{Duration, SystemTime},
5};
6
7use humantime::TimestampError;
8use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer};
9
10use casper_types::bytesrepr::{self, ToBytes};
11
12/// A timestamp newtype, representing a specific moment in time.
13#[derive(Copy, Clone, Default, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)]
14pub struct Timestamp(u64);
15
16impl Timestamp {
17    /// Returns the timestamp of the current moment.
18    pub fn now() -> Self {
19        let millis = SystemTime::UNIX_EPOCH
20            .elapsed()
21            .unwrap_or_default()
22            .as_millis() as u64;
23        Timestamp(millis)
24    }
25}
26
27impl Display for Timestamp {
28    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
29        match SystemTime::UNIX_EPOCH.checked_add(Duration::from_millis(self.0)) {
30            Some(system_time) => write!(
31                formatter,
32                "{}",
33                humantime::format_rfc3339_millis(system_time)
34            ),
35            None => write!(
36                formatter,
37                "invalid Timestamp: {} ms after the Unix epoch",
38                self.0
39            ),
40        }
41    }
42}
43
44impl FromStr for Timestamp {
45    type Err = TimestampError;
46
47    fn from_str(value: &str) -> Result<Self, Self::Err> {
48        let system_time = humantime::parse_rfc3339_weak(value)?;
49        let inner = system_time
50            .duration_since(SystemTime::UNIX_EPOCH)
51            .map_err(|_| TimestampError::OutOfRange)?
52            .as_millis() as u64;
53        Ok(Timestamp(inner))
54    }
55}
56
57impl Serialize for Timestamp {
58    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
59        if serializer.is_human_readable() {
60            self.to_string().serialize(serializer)
61        } else {
62            self.0.serialize(serializer)
63        }
64    }
65}
66
67impl<'de> Deserialize<'de> for Timestamp {
68    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
69        if deserializer.is_human_readable() {
70            let value_as_string = String::deserialize(deserializer)?;
71            Timestamp::from_str(&value_as_string).map_err(SerdeError::custom)
72        } else {
73            let inner = u64::deserialize(deserializer)?;
74            Ok(Timestamp(inner))
75        }
76    }
77}
78
79impl ToBytes for Timestamp {
80    fn write_bytes(&self, buffer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
81        self.0.write_bytes(buffer)
82    }
83
84    fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
85        self.0.to_bytes()
86    }
87
88    fn serialized_length(&self) -> usize {
89        self.0.serialized_length()
90    }
91}