use iso8601;
pub fn duration_string_to_seconds(duration_str: &str) -> Result<i64, String> {
let duration_str = duration_str.trim();
if duration_str.is_empty() {
return Err("Duration string cannot be empty".to_string());
}
let duration = iso8601::duration(duration_str)
.map_err(|e| format!("Invalid ISO 8601 duration format: {}", e))?;
let mut total_seconds = 0_i64;
match duration {
iso8601::Duration::YMDHMS {
year,
month,
day,
hour,
minute,
second,
millisecond,
} => {
total_seconds = total_seconds
.checked_add(year as i64 * 31_557_600)
.ok_or("Duration too large, would cause overflow")?;
total_seconds = total_seconds
.checked_add(month as i64 * 2_629_800)
.ok_or("Duration too large, would cause overflow")?;
total_seconds = total_seconds
.checked_add(day as i64 * 86_400)
.ok_or("Duration too large, would cause overflow")?;
total_seconds = total_seconds
.checked_add(hour as i64 * 3_600)
.ok_or("Duration too large, would cause overflow")?;
total_seconds = total_seconds
.checked_add(minute as i64 * 60)
.ok_or("Duration too large, would cause overflow")?;
total_seconds = total_seconds
.checked_add(second as i64)
.ok_or("Duration too large, would cause overflow")?;
total_seconds = total_seconds
.checked_add(millisecond as i64 / 1000)
.ok_or("Duration too large, would cause overflow")?;
}
iso8601::Duration::Weeks(weeks) => {
total_seconds = total_seconds
.checked_add(weeks as i64 * 604_800)
.ok_or("Duration too large, would cause overflow")?;
}
}
Ok(total_seconds)
}