templar_primitives/
time.rs1use crate::strnum::SU64;
2use alloc::fmt;
3#[cfg(feature = "schemars")]
4use alloc::string::String;
5#[cfg(any(feature = "borsh", feature = "schemars"))]
6use alloc::string::ToString;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10#[cfg_attr(feature = "serde", serde(transparent))]
11#[cfg_attr(
12 feature = "borsh",
13 derive(borsh::BorshSerialize, borsh::BorshDeserialize, borsh::BorshSchema)
14)]
15pub struct Nanoseconds(SU64);
16
17#[cfg(feature = "schemars")]
18impl schemars::JsonSchema for Nanoseconds {
19 fn schema_name() -> String {
20 "Nanoseconds".to_string()
21 }
22
23 fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
24 let mut schema = schemars::schema::SchemaObject::default();
25 schema.instance_type = Some(schemars::schema::InstanceType::String.into());
26 schema.metadata().description =
27 Some("nanoseconds represented as a decimal string".to_string());
28 schema.into()
29 }
30}
31
32impl Nanoseconds {
33 pub const fn zero() -> Self {
34 Self(SU64::new(0))
35 }
36
37 pub const fn from_ns(value: u64) -> Self {
39 Self(SU64::new(value))
40 }
41
42 pub const fn from_micros(value: u64) -> Self {
44 Self(SU64::new(value.saturating_mul(1_000)))
45 }
46
47 pub const fn from_ms(value: u64) -> Self {
49 Self(SU64::new(value.saturating_mul(1_000_000)))
50 }
51
52 pub const fn from_secs(value: u64) -> Self {
54 Self(SU64::new(value.saturating_mul(1_000_000_000)))
55 }
56
57 pub const fn as_secs(&self) -> u64 {
59 self.0 .0 / 1_000_000_000
60 }
61
62 pub const fn as_ms(&self) -> u64 {
64 self.0 .0 / 1_000_000
65 }
66
67 pub const fn as_micros(&self) -> u64 {
69 self.0 .0 / 1_000
70 }
71
72 pub const fn as_ns(&self) -> u64 {
74 self.0 .0
75 }
76
77 #[must_use]
78 pub const fn saturating_add(self, rhs: Self) -> Self {
79 Self(SU64::new(self.0 .0.saturating_add(rhs.0 .0)))
80 }
81
82 #[must_use]
83 pub const fn saturating_sub(self, rhs: Self) -> Self {
84 Self(SU64::new(self.0 .0.saturating_sub(rhs.0 .0)))
85 }
86}
87
88impl fmt::Display for Nanoseconds {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 write!(f, "{}ns", self.as_ns())
91 }
92}
93
94#[cfg(feature = "near")]
95mod near {
96 impl super::Nanoseconds {
97 pub fn near_timestamp() -> Self {
98 Self::from_ns(near_sdk::env::block_timestamp())
99 }
100 }
101}
102
103#[cfg(feature = "redstone")]
104mod redstone {
105 impl From<redstone::TimestampMillis> for super::Nanoseconds {
106 fn from(value: redstone::TimestampMillis) -> Self {
107 Self::from_ms(value.as_millis())
108 }
109 }
110
111 impl From<super::Nanoseconds> for redstone::TimestampMillis {
112 fn from(value: super::Nanoseconds) -> Self {
113 Self::from_millis(value.as_ms())
114 }
115 }
116}