aion/
lib.rs

1use chrono::{DateTime, Duration, Utc};
2
3pub trait DurationExtension {
4    fn weeks(self) -> Duration;
5    fn days(self) -> Duration;
6    fn hours(self) -> Duration;
7    fn minutes(self) -> Duration;
8    fn seconds(self) -> Duration;
9    fn milliseconds(self) -> Duration;
10    fn microseconds(self) -> Duration;
11    fn nanoseconds(self) -> Duration;
12}
13
14pub trait DateTimeExtension {
15    fn before(self, other: DateTime<Utc>) -> DateTime<Utc>;
16    fn after(self, other: DateTime<Utc>) -> DateTime<Utc>;
17
18    fn ago(self) -> DateTime<Utc>
19    where
20        Self: DateTimeExtension + Sized,
21    {
22        self.before(Utc::now())
23    }
24
25    fn from_now(self) -> DateTime<Utc>
26    where
27        Self: DateTimeExtension + Sized,
28    {
29        self.after(Utc::now())
30    }
31}
32
33macro_rules! duration_extension {
34    ($($type:ident), +) => {
35        impl DurationExtension for i64 {
36            $(
37                fn $type(self) -> Duration {
38                    Duration::$type(self)
39                }
40            )*
41        }
42    };
43}
44duration_extension!(
45    weeks,
46    days,
47    hours,
48    minutes,
49    seconds,
50    milliseconds,
51    microseconds,
52    nanoseconds
53);
54
55impl DateTimeExtension for Duration {
56    fn before(self, other: DateTime<Utc>) -> DateTime<Utc> {
57        other - self
58    }
59
60    fn after(self, other: DateTime<Utc>) -> DateTime<Utc> {
61        other + self
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68    use chrono::{Duration, Utc};
69
70    #[test]
71    fn duration() {
72        assert_eq!(2.weeks(), Duration::weeks(2));
73        assert_eq!(2.days(), Duration::days(2));
74        assert_eq!(2.hours(), Duration::hours(2));
75        assert_eq!(2.minutes(), Duration::minutes(2));
76        assert_eq!(2.seconds(), Duration::seconds(2));
77        assert_eq!(2.milliseconds(), Duration::milliseconds(2));
78        assert_eq!(2.microseconds(), Duration::microseconds(2));
79        assert_eq!(2.nanoseconds(), Duration::nanoseconds(2));
80    }
81
82    #[test]
83    fn days_before() {
84        let now = Utc::now();
85        assert_eq!(2.days().before(now), now - Duration::days(2));
86    }
87
88    #[test]
89    fn days_after() {
90        let now = Utc::now();
91        assert_eq!(2.days().after(now), now + Duration::days(2));
92    }
93}