1
#[derive(Clone, Debug, PartialEq)]
2
pub struct Duration {
3
    pub(crate) sign: i8,
4
    pub(crate) weeks: Option<u64>,
5
    pub(crate) days: Option<u64>,
6
    pub(crate) hours: Option<u64>,
7
    pub(crate) minutes: Option<u64>,
8
    pub(crate) seconds: Option<u64>,
9
}
10

            
11
impl Default for Duration {
12
16
    fn default() -> Self {
13
16
        Duration {
14
16
            sign: 1,
15
16
            weeks: None,
16
16
            days: None,
17
16
            hours: None,
18
16
            minutes: None,
19
16
            seconds: None,
20
16
        }
21
16
    }
22
}
23

            
24
impl Duration {
25
12
    pub fn weeks(sign: i8, weeks: u64) -> Self {
26
12
        Duration {
27
12
            sign,
28
12
            weeks: Some(weeks),
29
12
            days: None,
30
12
            hours: None,
31
12
            minutes: None,
32
12
            seconds: None,
33
12
        }
34
12
    }
35

            
36
24
    pub fn days(sign: i8, days: u64) -> Self {
37
24
        Duration {
38
24
            sign,
39
24
            weeks: None,
40
24
            days: Some(days),
41
24
            hours: None,
42
24
            minutes: None,
43
24
            seconds: None,
44
24
        }
45
24
    }
46

            
47
2
    pub fn days_and_time(sign: i8, days: u64) -> DurationTimeBuilder {
48
2
        DurationTimeBuilder {
49
2
            duration: Duration {
50
2
                sign,
51
2
                weeks: None,
52
2
                days: Some(days),
53
2
                hours: None,
54
2
                minutes: None,
55
2
                seconds: None,
56
2
            },
57
2
        }
58
2
    }
59

            
60
62
    pub fn hours(sign: i8, hours: u64) -> DurationTimeMinutesBuilder {
61
62
        DurationTimeMinutesBuilder {
62
62
            duration: Duration {
63
62
                sign,
64
62
                weeks: None,
65
62
                days: None,
66
62
                hours: Some(hours),
67
62
                minutes: None,
68
62
                seconds: None,
69
62
            },
70
62
        }
71
62
    }
72

            
73
    pub fn minutes(sign: i8, minutes: u64) -> DurationTimeSecondsBuilder {
74
        DurationTimeSecondsBuilder {
75
            duration: Duration {
76
                sign,
77
                weeks: None,
78
                days: None,
79
                hours: None,
80
                minutes: Some(minutes),
81
                seconds: None,
82
            },
83
        }
84
    }
85

            
86
    pub fn seconds(sign: i8, seconds: u64) -> Self {
87
        Duration {
88
            sign,
89
            weeks: None,
90
            days: None,
91
            hours: None,
92
            minutes: None,
93
            seconds: Some(seconds),
94
        }
95
    }
96

            
97
16
    pub fn to_std(self) -> (i8, std::time::Duration) {
98
16
        let secs = self
99
16
            .weeks
100
18
            .map(|weeks| weeks * 7 * 24 * 60 * 60)
101
16
            .unwrap_or(0)
102
18
            + self.days.map(|days| days * 24 * 60 * 60).unwrap_or(0)
103
20
            + self.hours.map(|hours| hours * 60 * 60).unwrap_or(0)
104
20
            + self.minutes.map(|minutes| minutes * 60).unwrap_or(0)
105
16
            + self.seconds.unwrap_or(0);
106
16

            
107
16
        (self.sign, std::time::Duration::from_secs(secs))
108
16
    }
109
}
110

            
111
pub struct DurationTimeBuilder {
112
    duration: Duration,
113
}
114

            
115
impl DurationTimeBuilder {
116
2
    pub fn hours(mut self, hours: u64) -> DurationTimeMinutesBuilder {
117
2
        self.duration.hours = Some(hours);
118
2
        DurationTimeMinutesBuilder {
119
2
            duration: self.duration,
120
2
        }
121
2
    }
122

            
123
    pub fn minutes(mut self, minutes: u64) -> DurationTimeSecondsBuilder {
124
        self.duration.minutes = Some(minutes);
125
        DurationTimeSecondsBuilder {
126
            duration: self.duration,
127
        }
128
    }
129

            
130
    pub fn seconds(mut self, seconds: u64) -> Duration {
131
        self.duration.seconds = Some(seconds);
132
        self.build()
133
    }
134

            
135
    pub fn build(self) -> Duration {
136
        self.duration
137
    }
138
}
139

            
140
pub struct DurationTimeMinutesBuilder {
141
    duration: Duration,
142
}
143

            
144
impl DurationTimeMinutesBuilder {
145
    pub fn minutes(mut self, minutes: u64) -> DurationTimeSecondsBuilder {
146
        self.duration.minutes = Some(minutes);
147
        DurationTimeSecondsBuilder {
148
            duration: self.duration,
149
        }
150
    }
151

            
152
64
    pub fn build(self) -> Duration {
153
64
        self.duration
154
64
    }
155
}
156

            
157
pub struct DurationTimeSecondsBuilder {
158
    duration: Duration,
159
}
160

            
161
impl DurationTimeSecondsBuilder {
162
    pub fn seconds(mut self, seconds: u64) -> Duration {
163
        self.duration.seconds = Some(seconds);
164
        self.build()
165
    }
166

            
167
    pub fn build(self) -> Duration {
168
        self.duration
169
    }
170
}