canic_host/duration/
mod.rs1use thiserror::Error as ThisError;
2
3#[derive(Debug, ThisError)]
7pub enum DurationParseError {
8 #[error("invalid duration {value:?}; use positive seconds or a value ending in s, m, h, or d")]
9 Invalid { value: String },
10}
11
12pub fn parse_duration_seconds(value: &str) -> Result<u64, DurationParseError> {
13 let (number, multiplier) = match value.as_bytes().last().copied() {
14 Some(b's') => (&value[..value.len() - 1], 1),
15 Some(b'm') => (&value[..value.len() - 1], 60),
16 Some(b'h') => (&value[..value.len() - 1], 60 * 60),
17 Some(b'd') => (&value[..value.len() - 1], 24 * 60 * 60),
18 Some(b'0'..=b'9') => (value, 1),
19 _ => return invalid_duration(value),
20 };
21 number
22 .parse::<u64>()
23 .ok()
24 .and_then(|amount| amount.checked_mul(multiplier))
25 .filter(|seconds| *seconds > 0)
26 .ok_or_else(|| DurationParseError::Invalid {
27 value: value.to_string(),
28 })
29}
30
31fn invalid_duration(value: &str) -> Result<u64, DurationParseError> {
32 Err(DurationParseError::Invalid {
33 value: value.to_string(),
34 })
35}
36
37#[cfg(test)]
38mod tests;