blob: cd7454b27ccf5651e370b7618f5af138d236e545 (
plain) (
blame)
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
|
// yt - A fully featured command line YouTube client
//
// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
// SPDX-License-Identifier: GPL-3.0-or-later
//
// This file is part of Yt.
//
// You should have received a copy of the License along with this program.
// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
// TODO: This file should be de-duplicated with the same file in the 'yt' crate <2024-06-25>
pub struct Duration {
time: u32,
}
impl From<&str> for Duration {
fn from(v: &str) -> Self {
let buf: Vec<_> = v.split(':').take(2).collect();
Self {
time: (buf[0].parse::<u32>().expect("Should be a number") * 60)
+ buf[1].parse::<u32>().expect("Should be a number"),
}
}
}
impl From<Option<f64>> for Duration {
fn from(value: Option<f64>) -> Self {
Self {
time: value.unwrap_or(0.0).ceil() as u32,
}
}
}
impl std::fmt::Display for Duration {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
const SECOND: u32 = 1;
const MINUTE: u32 = 60 * SECOND;
const HOUR: u32 = 60 * MINUTE;
let base_hour = self.time - (self.time % HOUR);
let base_min = (self.time % HOUR) - ((self.time % HOUR) % MINUTE);
let base_sec = (self.time % HOUR) % MINUTE;
let h = base_hour / HOUR;
let m = base_min / MINUTE;
let s = base_sec / SECOND;
if self.time == 0 {
write!(f, "0s")
} else if h > 0 {
write!(f, "{h}h {m}m")
} else {
write!(f, "{m}m {s}s")
}
}
}
#[cfg(test)]
mod test {
use super::Duration;
#[test]
fn test_display_duration_1h() {
let dur = Duration { time: 60 * 60 };
assert_eq!("[1h 0m]".to_owned(), dur.to_string());
}
#[test]
fn test_display_duration_30min() {
let dur = Duration { time: 60 * 30 };
assert_eq!("[30m 0s]".to_owned(), dur.to_string());
}
}
|