tezos_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 tezos_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]) -> tezos_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(&self, output: &mut Vec<u8>) -> tezos_data_encoding::enc::BinResult {
60            tezos_data_encoding::enc::i64(&self.0, output)
61        }
62    }
63
64    impl HasEncoding for Timestamp {
65        fn encoding() -> Encoding {
66            Encoding::Timestamp
67        }
68    }
69
70    impl std::fmt::Debug for Timestamp {
71        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72            std::fmt::Display::fmt(self, f)
73        }
74    }
75
76    impl std::fmt::Display for Timestamp {
77        /// Display timestamp in the RFC3339 human readable format.
78        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79            let rfc_3339 = OffsetDateTime::from_unix_timestamp(self.0)
80                .map_err(|_| String::from("timestamp out of range"))
81                .and_then(|t| {
82                    t.format(&Rfc3339)
83                        .map_err(|_| String::from("invalid timestamp"))
84                });
85
86            match rfc_3339 {
87                Ok(ts) => ts.fmt(f),
88                Err(err) => write!(f, "<invalid timestamp: {err}>"),
89            }
90        }
91    }
92}