ruso_runtime/runtime/
duration.rs1use std::time::Duration;
2
3use crate::runtime::error::RuntimeError;
4
5pub fn parse_duration(input: &str) -> Result<Duration, RuntimeError> {
19 let trimmed = input.trim();
20 let (digits, unit) =
21 split_suffix(trimmed).ok_or_else(|| RuntimeError::InvalidDuration(input.to_string()))?;
22 let value: u64 = digits
23 .trim()
24 .parse()
25 .map_err(|_| RuntimeError::InvalidDuration(input.to_string()))?;
26 let scaled = match unit {
27 "ms" => Duration::from_millis(value),
28 "s" => Duration::from_secs(value),
29 "m" => Duration::from_secs(value.saturating_mul(60)),
30 "h" => Duration::from_secs(value.saturating_mul(3600)),
31 "d" => Duration::from_secs(value.saturating_mul(86_400)),
32 _ => return Err(RuntimeError::InvalidDuration(input.to_string())),
33 };
34 Ok(scaled)
35}
36
37fn split_suffix(input: &str) -> Option<(&str, &str)> {
40 for suffix in ["ms", "s", "m", "h", "d"] {
41 if let Some(stripped) = input.strip_suffix(suffix) {
42 return Some((stripped, suffix));
43 }
44 }
45 None
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn ms_unit() {
54 assert_eq!(parse_duration("250ms").unwrap(), Duration::from_millis(250));
55 }
56
57 #[test]
58 fn s_unit() {
59 assert_eq!(parse_duration("3s").unwrap(), Duration::from_secs(3));
60 }
61
62 #[test]
63 fn m_unit() {
64 assert_eq!(parse_duration("5m").unwrap(), Duration::from_secs(300));
65 }
66
67 #[test]
68 fn h_unit() {
69 assert_eq!(parse_duration("2h").unwrap(), Duration::from_secs(7200));
70 }
71
72 #[test]
73 fn d_unit() {
74 assert_eq!(parse_duration("1d").unwrap(), Duration::from_secs(86_400));
75 }
76
77 #[test]
78 fn ms_wins_over_s_suffix() {
79 assert_eq!(parse_duration("500ms").unwrap(), Duration::from_millis(500));
81 }
82
83 #[test]
84 fn rejects_missing_suffix() {
85 assert!(parse_duration("42").is_err());
86 }
87
88 #[test]
89 fn rejects_unknown_suffix() {
90 assert!(parse_duration("5z").is_err());
91 }
92
93 #[test]
94 fn rejects_negative_value() {
95 assert!(parse_duration("-1s").is_err());
96 }
97}