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 _ => {
20 return Err(DurationParseError::Invalid {
21 value: value.to_string(),
22 });
23 }
24 };
25 number
26 .parse::<u64>()
27 .ok()
28 .and_then(|amount| amount.checked_mul(multiplier))
29 .filter(|seconds| *seconds > 0)
30 .ok_or_else(|| DurationParseError::Invalid {
31 value: value.to_string(),
32 })
33}
34
35#[cfg(test)]
36mod tests;