blob: 8ef61ed1aa9b32c62ade1a7462123443dd66f389 [file] [edit]
use std::time::Duration;
use crate::CargoResult;
/// Parses a time span string.
pub fn parse_time_span(span: &str) -> CargoResult<Duration> {
maybe_parse_time_span(span).ok_or_else(|| {
anyhow::format_err!(
"expected a value of the form \
\"N seconds/minutes/hours/days/weeks/months\", got: {span:?}"
)
})
}
/// Parses a time span string.
///
/// Returns None if the value is not valid. See [`parse_time_span`] if you
/// need a variant that generates an error message.
pub fn maybe_parse_time_span(span: &str) -> Option<Duration> {
let Some(right_i) = span.find(|c: char| !c.is_ascii_digit()) else {
return None;
};
let (left, mut right) = span.split_at(right_i);
if right.starts_with(' ') {
right = &right[1..];
}
let count: u64 = left.parse().ok()?;
let factor = match right {
"second" | "seconds" => 1,
"minute" | "minutes" => 60,
"hour" | "hours" => 60 * 60,
"day" | "days" => 24 * 60 * 60,
"week" | "weeks" => 7 * 24 * 60 * 60,
"month" | "months" => 2_629_746, // average is 30.436875 days
_ => return None,
};
Some(Duration::from_secs(factor * count))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn time_spans() {
let d = |x| Some(Duration::from_secs(x));
assert_eq!(maybe_parse_time_span("0 seconds"), d(0));
assert_eq!(maybe_parse_time_span("1second"), d(1));
assert_eq!(maybe_parse_time_span("23 seconds"), d(23));
assert_eq!(maybe_parse_time_span("5 minutes"), d(60 * 5));
assert_eq!(maybe_parse_time_span("2 hours"), d(60 * 60 * 2));
assert_eq!(maybe_parse_time_span("1 day"), d(60 * 60 * 24));
assert_eq!(maybe_parse_time_span("2 weeks"), d(60 * 60 * 24 * 14));
assert_eq!(maybe_parse_time_span("6 months"), d(2_629_746 * 6));
}
#[test]
fn time_span_errors() {
assert_eq!(maybe_parse_time_span(""), None);
assert_eq!(maybe_parse_time_span("1"), None);
assert_eq!(maybe_parse_time_span("second"), None);
assert_eq!(maybe_parse_time_span("+2 seconds"), None);
assert_eq!(maybe_parse_time_span("day"), None);
assert_eq!(maybe_parse_time_span("-1 days"), None);
assert_eq!(maybe_parse_time_span("1.5 days"), None);
assert_eq!(maybe_parse_time_span("1 dayz"), None);
assert_eq!(maybe_parse_time_span("always"), None);
assert_eq!(maybe_parse_time_span("never"), None);
assert_eq!(maybe_parse_time_span("1 day "), None);
assert_eq!(maybe_parse_time_span(" 1 day"), None);
assert_eq!(maybe_parse_time_span("1 second"), None);
}
}