1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use std::time::Duration;

/// A trait to simplify construction a [`std::time::Duration`] from numeric types.
///
/// The trait is implemented for the common numeric types, like [`i32`], [`u32`], ...
///
/// Note that for signed integers, the absolute value will be used.
pub trait EasyDuration: Sized {
    fn seconds(self) -> Duration;

    fn minutes(self) -> Duration {
        self.seconds() * 60
    }

    fn hours(self) -> Duration {
        self.seconds() * 60 * 60
    }

    fn days(self) -> Duration {
        self.seconds() * 60 * 60 * 24
    }
}

impl EasyDuration for u8 {
    fn seconds(self) -> Duration {
        Duration::from_secs(self.into())
    }
}

impl EasyDuration for u16 {
    fn seconds(self) -> Duration {
        Duration::from_secs(self.into())
    }
}

impl EasyDuration for u32 {
    fn seconds(self) -> Duration {
        Duration::from_secs(self.into())
    }
}

impl EasyDuration for u64 {
    fn seconds(self) -> Duration {
        Duration::from_secs(self)
    }
}

impl EasyDuration for i8 {
    fn seconds(self) -> Duration {
        Duration::from_secs(self.unsigned_abs() as u64)
    }
}

impl EasyDuration for i16 {
    fn seconds(self) -> Duration {
        Duration::from_secs(self.unsigned_abs() as u64)
    }
}

impl EasyDuration for i32 {
    fn seconds(self) -> Duration {
        let secs = self.abs().try_into().unwrap();
        Duration::from_secs(secs)
    }
}

impl EasyDuration for i64 {
    fn seconds(self) -> Duration {
        let secs = self.abs().try_into().unwrap();
        Duration::from_secs(secs)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_easy_duration() {
        // Seconds.
        assert_eq!(1i8.seconds(), Duration::from_secs(1));
        assert_eq!(1i16.seconds(), Duration::from_secs(1));
        assert_eq!(1i32.seconds(), Duration::from_secs(1));
        assert_eq!(1i64.seconds(), Duration::from_secs(1));
        assert_eq!(1u8.seconds(), Duration::from_secs(1));
        assert_eq!(1u16.seconds(), Duration::from_secs(1));
        assert_eq!(1u32.seconds(), Duration::from_secs(1));
        assert_eq!(1u64.seconds(), Duration::from_secs(1));

        // Minutes
        assert_eq!(1i8.minutes(), Duration::from_secs(60));
        assert_eq!(1i16.minutes(), Duration::from_secs(60));
        assert_eq!(1i32.minutes(), Duration::from_secs(60));
        assert_eq!(1i64.minutes(), Duration::from_secs(60));
        assert_eq!(1u8.minutes(), Duration::from_secs(60));
        assert_eq!(1u16.minutes(), Duration::from_secs(60));
        assert_eq!(1u32.minutes(), Duration::from_secs(60));
        assert_eq!(1u64.minutes(), Duration::from_secs(60));

        // Hours.
        assert_eq!(1i8.hours(), Duration::from_secs(60 * 60));
        assert_eq!(1i16.hours(), Duration::from_secs(60 * 60));
        assert_eq!(1i32.hours(), Duration::from_secs(60 * 60));
        assert_eq!(1i64.hours(), Duration::from_secs(60 * 60));
        assert_eq!(1u8.hours(), Duration::from_secs(60 * 60));
        assert_eq!(1u16.hours(), Duration::from_secs(60 * 60));
        assert_eq!(1u32.hours(), Duration::from_secs(60 * 60));
        assert_eq!(1u64.hours(), Duration::from_secs(60 * 60));

        // Days.
        assert_eq!(1i8.days(), Duration::from_secs(60 * 60 * 24));
        assert_eq!(1i16.days(), Duration::from_secs(60 * 60 * 24));
        assert_eq!(1i32.days(), Duration::from_secs(60 * 60 * 24));
        assert_eq!(1i64.days(), Duration::from_secs(60 * 60 * 24));
        assert_eq!(1u8.days(), Duration::from_secs(60 * 60 * 24));
        assert_eq!(1u16.days(), Duration::from_secs(60 * 60 * 24));
        assert_eq!(1u32.days(), Duration::from_secs(60 * 60 * 24));
        assert_eq!(1u64.days(), Duration::from_secs(60 * 60 * 24));
    }
}