aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-02-14 16:44:53 +0100
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-02-14 16:44:53 +0100
commit14db4eadd57d0a3837227d9d74b84a133bacd434 (patch)
tree6a269bb25cf7204cfbdf776a12eeb3490a1ed6cd
parentfix(yt/download/download_options): Stop trying to write annotations (diff)
downloadyt-14db4eadd57d0a3837227d9d74b84a133bacd434.zip
feat(yt/select/selection_file/duration): Support durations up to days
The current maximum of hours was enough in most cases, but not for all cases.
-rw-r--r--yt/src/select/selection_file/duration.rs61
1 files changed, 43 insertions, 18 deletions
diff --git a/yt/src/select/selection_file/duration.rs b/yt/src/select/selection_file/duration.rs
index ab3a18b..2953bd3 100644
--- a/yt/src/select/selection_file/duration.rs
+++ b/yt/src/select/selection_file/duration.rs
@@ -14,19 +14,36 @@ use anyhow::{Context, Result};
use crate::unreachable::Unreachable;
+const SECOND: u64 = 1;
+const MINUTE: u64 = 60 * SECOND;
+const HOUR: u64 = 60 * MINUTE;
+const DAY: u64 = 24 * HOUR;
+
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Duration {
- time: u32,
+ time: u64,
+}
+
+impl Duration {
+ #[must_use]
+ pub fn from_std(d: std::time::Duration) -> Self {
+ Self { time: d.as_secs() }
+ }
+
+ #[must_use]
+ pub fn value(&self) -> u64 {
+ self.time
+ }
}
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> {
+ fn parse_num(str: &str, suffix: char) -> Result<u64> {
str.strip_suffix(suffix)
.with_context(|| format!("Failed to strip suffix '{suffix}' of number: '{str}'"))?
- .parse::<u32>()
+ .parse::<u64>()
.with_context(|| format!("Failed to parse '{suffix}'"))
}
@@ -36,17 +53,25 @@ impl FromStr for Duration {
let buf: Vec<_> = s.split(' ').collect();
+ let days;
let hours;
let minutes;
let seconds;
assert_eq!(buf.len(), 2, "Other lengths should not happen");
- if buf[0].ends_with('h') {
+ if buf[0].ends_with('d') {
+ days = parse_num(buf[0], 'd')?;
+ hours = parse_num(buf[1], 'h')?;
+ minutes = parse_num(buf[2], 'm')?;
+ seconds = 0;
+ } else if buf[0].ends_with('h') {
+ days = 0;
hours = parse_num(buf[0], 'h')?;
minutes = parse_num(buf[1], 'm')?;
seconds = 0;
} else if buf[0].ends_with('m') {
+ days = 0;
hours = 0;
minutes = parse_num(buf[0], 'm')?;
seconds = parse_num(buf[1], 's')?;
@@ -58,7 +83,7 @@ impl FromStr for Duration {
}
Ok(Self {
- time: (hours * 60 * 60) + (minutes * 60) + seconds,
+ time: days * DAY + hours * HOUR + minutes * MINUTE + seconds * SECOND,
})
}
}
@@ -67,32 +92,32 @@ impl From<Option<f64>> for Duration {
fn from(value: Option<f64>) -> Self {
Self {
#[allow(clippy::cast_possible_truncation)]
- time: u32::try_from(value.unwrap_or(0.0).ceil() as i128)
- .unreachable("This should not exceed `u32::MAX`"),
+ time: u64::try_from(value.unwrap_or(0.0).ceil() as i128)
+ .unreachable("This should not exceed `u64::MAX`"),
}
}
}
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;
+ fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
+ let base_day = self.time - (self.time % DAY);
+ let base_hour = (self.time % DAY) - ((self.time % DAY) % HOUR);
+ let base_min = (self.time % HOUR) - (((self.time % DAY) % HOUR) % MINUTE);
+ let base_sec = ((self.time % DAY) % HOUR) % MINUTE;
+ let d = base_day / DAY;
let h = base_hour / HOUR;
let m = base_min / MINUTE;
let s = base_sec / SECOND;
if self.time == 0 {
- write!(f, "[No duration]")
+ write!(fmt, "[No duration]")
+ } else if d > 0 {
+ write!(fmt, "{d}d {h}h {m}m")
} else if h > 0 {
- write!(f, "{h}h {m}m")
+ write!(fmt, "{h}h {m}m")
} else {
- write!(f, "{m}m {s}s")
+ write!(fmt, "{m}m {s}s")
}
}
}