Skip to main content

arg_parsing/
lib.rs

1// Copyright 2025 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::time::Duration;
6
7const DURATION_REGEX: &'static str = r"^(\d+)(h|m|s|ms)$";
8
9/// Parses a Duration from string.
10pub 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}