1use core::{
2 ops::{Add, AddAssign},
3 time::Duration,
4};
5use std::io;
6
7use chrono::{DateTime, Utc};
8use defuse_borsh_utils::adapters::{BorshDeserializeAs, BorshSerializeAs, TimestampNanoSeconds};
9use near_sdk::near;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
12#[near(serializers=[json])]
13#[repr(transparent)]
14pub struct Deadline(
15 #[cfg_attr(
16 all(feature = "abi", not(target_arch = "wasm32")),
17 schemars(with = "String")
18 )]
19 DateTime<Utc>,
20);
21
22impl Deadline {
23 pub const MAX: Self = Self(DateTime::<Utc>::MAX_UTC);
24
25 pub const fn new(d: DateTime<Utc>) -> Self {
26 Self(d)
27 }
28
29 #[cfg(target_arch = "wasm32")]
30 #[must_use]
31 pub fn now() -> Self {
32 Self(defuse_near_utils::time::now())
33 }
34
35 #[cfg(not(target_arch = "wasm32"))]
36 #[must_use]
37 #[inline]
38 pub fn now() -> Self {
39 Self(Utc::now())
40 }
41
42 #[must_use]
43 #[inline]
44 pub fn timeout(timeout: Duration) -> Self {
45 Self::now() + timeout
46 }
47
48 #[must_use]
49 #[inline]
50 pub fn has_expired(self) -> bool {
51 Self::now() > self
52 }
53
54 #[must_use]
55 #[inline]
56 pub const fn into_timestamp(self) -> DateTime<Utc> {
57 self.0
58 }
59}
60
61impl Add<Duration> for Deadline {
62 type Output = Self;
63
64 #[inline]
65 fn add(self, rhs: Duration) -> Self::Output {
66 Self(self.0 + rhs)
67 }
68}
69
70impl AddAssign<Duration> for Deadline {
71 #[inline]
72 fn add_assign(&mut self, rhs: Duration) {
73 self.0 += rhs;
74 }
75}
76
77impl BorshSerializeAs<Deadline> for TimestampNanoSeconds {
78 fn serialize_as<W>(source: &Deadline, writer: &mut W) -> io::Result<()>
79 where
80 W: io::Write,
81 {
82 Self::serialize_as(&source.0, writer)
83 }
84}
85
86impl BorshDeserializeAs<Deadline> for TimestampNanoSeconds {
87 fn deserialize_as<R>(reader: &mut R) -> io::Result<Deadline>
88 where
89 R: io::Read,
90 {
91 Self::deserialize_as(reader).map(Deadline)
92 }
93}