1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use cosmwasm_std::{BlockInfo, Timestamp};
5
6#[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}