Skip to content

Commit cce6dca

Browse files
committed
Added seconds parsing to time options
1 parent 2bc8232 commit cce6dca

File tree

3 files changed

+26
-43
lines changed

3 files changed

+26
-43
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "koshelf"
3-
version = "1.2.1"
3+
version = "1.2.2"
44
description = "Transform your KOReader library into a beautiful reading dashboard with statistics."
55
repository = "https://github.com/paviro/KOShelf"
66
license = "EUPL-1.2 license"
@@ -53,7 +53,7 @@ rusqlite = { version = "0.36.0", features = ["bundled"] }
5353
minify-html = "0.15" # 0.16 has an issue with inline js
5454
chrono-tz = "0.8"
5555
md5 = "0.8.0"
56+
regex = "1.12.2"
5657

5758
[dev-dependencies]
58-
regex = "1.12.2"
5959
ureq = { version = "3.1.4", features = ["json"] }

src/main.rs

Lines changed: 23 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use clap::Parser;
22
use std::path::PathBuf;
33
use anyhow::{Result, Context};
4+
use regex::Regex;
45
use log::info;
56

67
mod models;
@@ -93,54 +94,36 @@ struct Cli {
9394
github: bool,
9495
}
9596

96-
// Parse time format strings like "1h", "1h30m", "45min" into seconds
97+
// Parse time format strings like "1h", "1h30m", "45min", "30s" into seconds
9798
fn parse_time_to_seconds(time_str: &str) -> Result<Option<u32>> {
98-
if time_str == "auto" {
99+
if time_str.eq_ignore_ascii_case("auto") {
99100
return Ok(None);
100101
}
101-
102-
let time_str = time_str.to_lowercase();
103-
let mut total_seconds = 0u32;
104-
105-
// Handle hours
106-
if let Some(h_pos) = time_str.find('h') {
107-
let hours_str = &time_str[..h_pos];
108-
if let Ok(hours) = hours_str.parse::<u32>() {
109-
total_seconds += hours * 3600;
110-
} else {
111-
anyhow::bail!("Invalid hour format in: {}", time_str);
112-
}
113-
114-
// Check for minutes after hours
115-
let remaining = &time_str[h_pos + 1..];
116-
if !remaining.is_empty() {
117-
// Remove common minute suffixes and parse
118-
let remaining = remaining.replace("min", "").replace('m', "");
119-
if !remaining.is_empty() {
120-
if let Ok(minutes) = remaining.parse::<u32>() {
121-
if minutes >= 60 {
122-
anyhow::bail!("Minutes cannot be 60 or more: {}", time_str);
123-
}
124-
total_seconds += minutes * 60;
125-
} else {
126-
anyhow::bail!("Invalid minute format in: {}", time_str);
127-
}
128-
}
129-
}
130-
} else {
131-
// Only minutes specified
132-
let minutes_str = time_str.replace("min", "").replace('m', "");
133-
if let Ok(minutes) = minutes_str.parse::<u32>() {
134-
total_seconds = minutes * 60;
135-
} else {
136-
anyhow::bail!("Invalid time format: {}", time_str);
102+
103+
let re = Regex::new(r"(?i)(\d+)(h|m|min|s)")?;
104+
let mut total_seconds: u32 = 0;
105+
let mut matched_any = false;
106+
107+
for cap in re.captures_iter(time_str) {
108+
matched_any = true;
109+
let value: u32 = cap[1].parse()?;
110+
let unit = &cap[2].to_lowercase();
111+
112+
match unit.as_str() {
113+
"h" => total_seconds += value * 3600,
114+
"m" | "min" => total_seconds += value * 60,
115+
"s" => total_seconds += value,
116+
_ => anyhow::bail!("Unknown time unit: {}", unit),
137117
}
138118
}
139-
119+
120+
if !matched_any {
121+
anyhow::bail!("Invalid time format: {}", time_str);
122+
}
140123
if total_seconds == 0 {
141124
anyhow::bail!("Time cannot be zero: {}", time_str);
142125
}
143-
126+
144127
Ok(Some(total_seconds))
145128
}
146129

0 commit comments

Comments
 (0)