tg_utils/
time.rs

1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use cosmwasm_std::{BlockInfo, Timestamp};
5
6/// Duration is an amount of time, measured in seconds
7#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, JsonSchema, Debug)]
8pub struct Duration(u64);
9
10impl Duration {
11    pub fn new(secs: u64) -> Duration {
12        Duration(secs)
13    }
14
15    pub fn after(&self, block: &BlockInfo) -> Expiration {
16        self.after_time(block.time)
17    }
18
19    pub fn after_time(&self, timestamp: Timestamp) -> Expiration {
20        Expiration::at_timestamp(timestamp.plus_seconds(self.0))
21    }
22
23    pub fn seconds(&self) -> u64 {
24        self.0
25    }
26}
27
28#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, JsonSchema, Debug)]
29pub struct Expiration(Timestamp);
30
31impl Expiration {
32    pub fn now(block: &BlockInfo) -> Self {
33        Self(block.time)
34    }
35
36    pub fn at_timestamp(timestamp: Timestamp) -> Self {
37        Self(timestamp)
38    }
39
40    pub fn is_expired(&self, block: &BlockInfo) -> bool {
41        self.is_expired_time(block.time)
42    }
43
44    pub fn is_expired_time(&self, timestamp: Timestamp) -> bool {
45        timestamp >= self.0
46    }
47
48    pub fn time(&self) -> Timestamp {
49        self.0
50    }
51
52    pub fn as_key(&self) -> u64 {
53        self.0.nanos()
54    }
55}
56impl From<Expiration> for Timestamp {
57    fn from(expiration: Expiration) -> Timestamp {
58        expiration.0
59    }
60}
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    use cosmwasm_std::{BlockInfo, Timestamp};
66
67    use crate::Duration;
68
69    #[test]
70    fn create_expiration_from_duration() {
71        let duration = Duration::new(33);
72        let block_info = BlockInfo {
73            height: 1,
74            time: Timestamp::from_seconds(66),
75            chain_id: "id".to_owned(),
76        };
77        assert_eq!(
78            duration.after(&block_info),
79            Expiration::at_timestamp(Timestamp::from_seconds(99))
80        );
81    }
82
83    #[test]
84    fn expiration_is_expired() {
85        let expiration = Expiration::at_timestamp(Timestamp::from_seconds(10));
86        let block_info = BlockInfo {
87            height: 1,
88            time: Timestamp::from_seconds(9),
89            chain_id: "id".to_owned(),
90        };
91        assert!(!expiration.is_expired(&block_info));
92        let block_info = BlockInfo {
93            height: 1,
94            time: Timestamp::from_seconds(10),
95            chain_id: "id".to_owned(),
96        };
97        assert!(expiration.is_expired(&block_info));
98        let block_info = BlockInfo {
99            height: 1,
100            time: Timestamp::from_seconds(11),
101            chain_id: "id".to_owned(),
102        };
103        assert!(expiration.is_expired(&block_info));
104    }
105}