about summary refs log tree commit diff stats
path: root/yt_dlp/src/duration.rs
diff options
context:
space:
mode:
Diffstat (limited to 'yt_dlp/src/duration.rs')
-rw-r--r--yt_dlp/src/duration.rs71
1 files changed, 71 insertions, 0 deletions
diff --git a/yt_dlp/src/duration.rs b/yt_dlp/src/duration.rs
new file mode 100644
index 0000000..cd7454b
--- /dev/null
+++ b/yt_dlp/src/duration.rs
@@ -0,0 +1,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());
+    }
+}