Skip to main content

conf_extra/
duration.rs

1use core::time::Duration;
2
3#[cfg(feature = "chrono")]
4use chrono::TimeDelta;
5
6/// Parse a `std::time::Duration` from human-readable string using endings like d, h, m, s, ms, ns
7/// e.g. "500ms", "4h15m", etc.
8/// See docu for `go-parse-duration` crate for details on the format
9pub fn parse_duration(s: &str) -> Result<Duration, String> {
10    let nanos = go_parse_duration::parse_duration(s).map_err(|e| format!("{e:?}"))?;
11    let nanos = u64::try_from(nanos).map_err(|e| e.to_string())?;
12    Ok(Duration::from_nanos(nanos))
13}
14
15/// Parse a `chrono::TimeDelta` from a string using endings like d, h, m, s, ms, ns
16/// e.g. "500ms", "4h15m", etc.
17/// See docu for `go-parse-duration` crate for details on the format
18#[cfg(feature = "chrono")]
19pub fn parse_time_delta(s: &str) -> Result<TimeDelta, String> {
20    let nanos = go_parse_duration::parse_duration(s).map_err(|e| format!("{e:?}"))?;
21
22    let billion = 1_000_000_000;
23    let secs = nanos.div_euclid(billion);
24    let subsec_nanos = nanos.rem_euclid(billion) as u32;
25    TimeDelta::new(secs, subsec_nanos).ok_or_else(|| "invalid time delta".to_owned())
26}