1use std::time::Duration;
6
7const DURATION_REGEX: &'static str = r"^(\d+)(h|m|s|ms)$";
8
9pub fn parse_duration(value: &str) -> Result<Duration, String> {
11 let re = regex::Regex::new(DURATION_REGEX).unwrap();
12 let captures = re
13 .captures(&value)
14 .ok_or_else(|| format!("Durations must be specified in the form {}", DURATION_REGEX))?;
15 let number: u64 = captures[1].parse().unwrap();
16 let unit = &captures[2];
17
18 match unit {
19 "ms" => Ok(Duration::from_millis(number)),
20 "s" => Ok(Duration::from_secs(number)),
21 "m" => Ok(Duration::from_secs(number * 60)),
22 "h" => Ok(Duration::from_secs(number * 3600)),
23 _ => Err(format!(
24 "Invalid duration string \"{}\"; must be of the form {}",
25 value, DURATION_REGEX
26 )),
27 }
28}
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33
34 #[test]
35 fn test_parse_duration() {
36 assert_eq!(parse_duration("1h"), Ok(Duration::from_secs(3600)));
37 assert_eq!(parse_duration("3m"), Ok(Duration::from_secs(180)));
38 assert_eq!(parse_duration("10s"), Ok(Duration::from_secs(10)));
39 assert_eq!(parse_duration("100ms"), Ok(Duration::from_millis(100)));
40 }
41
42 #[test]
43 fn test_parse_duration_err() {
44 assert!(parse_duration("100").is_err());
45 assert!(parse_duration("10 0").is_err());
46 assert!(parse_duration("foobar").is_err());
47 }
48}