mavryk_smart_rollup_encoding/
timestamp.rs

1// SPDX-FileCopyrightText: 2020-2022 SimpleStaking, Viable Systems and Tezedge Contributors
2// SPDX-FileCopyrightText: 2023 TriliTech <contact@trili.tech>
3//
4// SPDX-License-Identifier: MIT
5
6//! Timestamp representation corresponding to L1 one
7//! Initially copied from tezedge
8//! [messages crate](https://github.com/emturner/tezedge/blob/7f4e1cd6e29282a5b6b5128381f42dab345ab50a/tezos/messages/src/lib.rs)
9#[cfg(feature = "alloc")]
10pub use encoding::Timestamp;
11
12#[cfg(feature = "alloc")]
13mod encoding {
14    use mavryk_data_encoding::{
15        enc::BinWriter,
16        encoding::{Encoding, HasEncoding},
17        nom::NomReader,
18    };
19    use time::{format_description::well_known::Rfc3339, OffsetDateTime};
20
21    /// Timestamp representation corresponding to one used in L1 messages
22    #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
23    pub struct Timestamp(i64);
24
25    impl Timestamp {
26        /// Convert timestamp to signed 64 bit int
27        pub fn i64(self) -> i64 {
28            self.0
29        }
30
31        /// Convert timestamp to unsigned 64 bit int
32        pub fn as_u64(self) -> u64 {
33            self.0 as u64
34        }
35    }
36
37    impl From<i64> for Timestamp {
38        fn from(source: i64) -> Self {
39            Self(source)
40        }
41    }
42
43    impl From<Timestamp> for i64 {
44        fn from(source: Timestamp) -> Self {
45            source.0
46        }
47    }
48
49    impl NomReader for Timestamp {
50        fn nom_read(input: &[u8]) -> mavryk_data_encoding::nom::NomResult<Self> {
51            nom::combinator::map(
52                nom::number::complete::i64(nom::number::Endianness::Big),
53                Timestamp,
54            )(input)
55        }
56    }
57
58    impl BinWriter for Timestamp {
59        fn bin_write(
60            &self,
61            output: &mut Vec<u8>,
62        ) -> mavryk_data_encoding::enc::BinResult {
63            mavryk_data_encoding::enc::i64(&self.0, output)
64        }
65    }
66
67    impl HasEncoding for Timestamp {
68        fn encoding() -> Encoding {
69            Encoding::Timestamp
70        }
71    }
72
73    impl std::fmt::Debug for Timestamp {
74        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75            std::fmt::Display::fmt(self, f)
76        }
77    }
78
79    impl std::fmt::Display for Timestamp {
80        /// Display timestamp in the RFC3339 human readable format.
81        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82            let rfc_3339 = OffsetDateTime::from_unix_timestamp(self.0)
83                .map_err(|_| String::from("timestamp out of range"))
84                .and_then(|t| {
85                    t.format(&Rfc3339)
86                        .map_err(|_| String::from("invalid timestamp"))
87                });
88
89            match rfc_3339 {
90                Ok(ts) => ts.fmt(f),
91                Err(err) => write!(f, "<invalid timestamp: {err}>"),
92            }
93        }
94    }
95}