about summary refs log tree commit diff stats
path: root/pkgs/by-name/yt/yt/src/select/selection_file/duration.rs
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/by-name/yt/yt/src/select/selection_file/duration.rs')
-rw-r--r--pkgs/by-name/yt/yt/src/select/selection_file/duration.rs52
1 files changed, 42 insertions, 10 deletions
diff --git a/pkgs/by-name/yt/yt/src/select/selection_file/duration.rs b/pkgs/by-name/yt/yt/src/select/selection_file/duration.rs
index 700d9202..9e4b3a83 100644
--- a/pkgs/by-name/yt/yt/src/select/selection_file/duration.rs
+++ b/pkgs/by-name/yt/yt/src/select/selection_file/duration.rs
@@ -1,14 +1,46 @@
+use std::str::FromStr;
+
+use anyhow::{Context, Result};
+
+#[derive(Copy, Clone, Debug)]
 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 FromStr for Duration {
+    type Err = anyhow::Error;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        fn parse_num(str: &str, suffix: char) -> Result<u32> {
+            str.strip_suffix(suffix)
+                .expect("it has a 'h' suffix")
+                .parse::<u32>()
+                .context("Failed to parse hours")
         }
+
+        let buf: Vec<_> = s.split(' ').collect();
+
+        let hours;
+        let minutes;
+        let seconds;
+
+        assert_eq!(buf.len(), 2, "Other lengths should not happen");
+
+        if buf[0].ends_with('h') {
+            hours = parse_num(buf[0], 'h')?;
+            minutes = parse_num(buf[1], 'm')?;
+            seconds = 0;
+        } else if buf[0].ends_with('m') {
+            hours = 0;
+            minutes = parse_num(buf[0], 'm')?;
+            seconds = parse_num(buf[1], 's')?;
+        } else {
+            unreachable!("The first part always ends with 'h' or 'm'")
+        }
+
+        Ok(Self {
+            time: (hours * 60 * 60) + (minutes * 60) + seconds,
+        })
     }
 }
 
@@ -37,9 +69,9 @@ impl std::fmt::Display for Duration {
         if self.time == 0 {
             write!(f, "[No Duration]")
         } else if h > 0 {
-            write!(f, "[{h}h {m}m]")
+            write!(f, "{h}h {m}m")
         } else {
-            write!(f, "[{m}m {s}s]")
+            write!(f, "{m}m {s}s")
         }
     }
 }
@@ -50,11 +82,11 @@ mod test {
     #[test]
     fn test_display_duration_1h() {
         let dur = Duration { time: 60 * 60 };
-        assert_eq!("[1h 0m]".to_owned(), dur.to_string());
+        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());
+        assert_eq!("30m 0s".to_owned(), dur.to_string());
     }
 }