1use std::thread;
6use std::time::Duration;
7
8use super::error::{Error, ErrorKind};
9
10pub fn sleep(number: &str) -> Result<(), Error> {
18 let time = parse_time(number)?;
19 thread::sleep(time);
20 Ok(())
21}
22
23fn parse_time(time: &str) -> Result<Duration, Error> {
24 let mut duration = Duration::new(0, 0);
25 for part in time.split_ascii_whitespace() {
26 let (has_suffix, multiple) = match part.chars().last() {
27 Some('s') => (true, 1),
28 Some('m') => (true, 60),
29 Some('h') => (true, 60 * 60),
30 Some('d') => (true, 24 * 60 * 60),
31 _ => (false, 1),
32 };
33
34 let interval = if has_suffix {
35 part.split_at(part.len() - 1).0
36 } else {
37 part
38 };
39 if let Ok(secs) = str::parse::<u64>(interval) {
40 duration += Duration::from_secs(secs * multiple);
41 } else {
42 return Err(Error::from_string(
43 ErrorKind::ParameterError,
44 format!("Invalid time interval `{:?}`", part),
45 ));
46 }
47 }
48
49 Ok(duration)
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn test_parse_time() {
58 assert_eq!(parse_time(" 3 \n").unwrap(), Duration::from_secs(3));
59 assert_eq!(parse_time("3").unwrap(), Duration::from_secs(3));
60 assert_eq!(parse_time("3s").unwrap(), Duration::from_secs(3));
61 assert_eq!(parse_time("3s 4").unwrap(), Duration::from_secs(7));
62 assert_eq!(
63 parse_time("3s 4m").unwrap(),
64 Duration::from_secs(3 + 4 * 60)
65 );
66
67 assert!(parse_time("3s 4a").is_err());
68 }
69}