#[cfg(feature = "alloc")]
pub use encoding::Timestamp;
#[cfg(feature = "alloc")]
mod encoding {
use tezos_data_encoding::{
enc::BinWriter,
encoding::{Encoding, HasEncoding},
nom::NomReader,
};
use time::{format_description::well_known::Rfc3339, OffsetDateTime};
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Timestamp(i64);
impl Timestamp {
pub fn i64(self) -> i64 {
self.0
}
pub fn as_u64(self) -> u64 {
self.0 as u64
}
}
impl From<i64> for Timestamp {
fn from(source: i64) -> Self {
Self(source)
}
}
impl From<Timestamp> for i64 {
fn from(source: Timestamp) -> Self {
source.0
}
}
impl NomReader for Timestamp {
fn nom_read(input: &[u8]) -> tezos_data_encoding::nom::NomResult<Self> {
nom::combinator::map(
nom::number::complete::i64(nom::number::Endianness::Big),
Timestamp,
)(input)
}
}
impl BinWriter for Timestamp {
fn bin_write(&self, output: &mut Vec<u8>) -> tezos_data_encoding::enc::BinResult {
tezos_data_encoding::enc::i64(&self.0, output)
}
}
impl HasEncoding for Timestamp {
fn encoding() -> Encoding {
Encoding::Timestamp
}
}
impl std::fmt::Debug for Timestamp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self, f)
}
}
impl std::fmt::Display for Timestamp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let rfc_3339 = OffsetDateTime::from_unix_timestamp(self.0)
.map_err(|_| String::from("timestamp out of range"))
.and_then(|t| {
t.format(&Rfc3339)
.map_err(|_| String::from("invalid timestamp"))
});
match rfc_3339 {
Ok(ts) => ts.fmt(f),
Err(err) => write!(f, "<invalid timestamp: {err}>"),
}
}
}
}