climer/time/parser/
mod.rs

1use regex::Regex;
2
3use super::{Time, TimeBuilder};
4use crate::error::{ClimerError, ClimerResult};
5use crate::settings::parser::codes::*;
6
7pub fn parse_time<T, U>(time: T, format_opt: Option<U>) -> ClimerResult<Time>
8where
9    T: ToString,
10    U: ToString,
11{
12    Ok(if let Some(format) = format_opt {
13        parse_time_with_format(time, format)?
14    } else {
15        parse_time_without_format(time)?
16    })
17}
18
19fn parse_time_without_format<T>(time: T) -> ClimerResult<Time>
20where
21    T: ToString,
22{
23    let time = time.to_string();
24    let replace_re = Regex::new(r"\s").unwrap();
25    let time = &replace_re.replace_all(&time, "");
26    let mut builder = TimeBuilder::new();
27    let mut remaining_input = time.to_string();
28    let input_re = Regex::new(r"(?P<num>\d+)(?P<ident>[a-zA-Z]+)").unwrap();
29    for caps in input_re.captures_iter(time) {
30        remaining_input = remaining_input.replace(&caps[0], "");
31        let num = caps["num"].parse().expect("Should unwrap to integer");
32        match &caps["ident"] {
33            HOUR => builder = builder.hours(num),
34            MINUTE => builder = builder.minutes(num),
35            SECOND => builder = builder.seconds(num),
36            MILLISECOND => builder = builder.milliseconds(num),
37            NANOSECOND => builder = builder.nanoseconds(num),
38            _ => {
39                return Err(ClimerError::InvalidTimeIdentifier(
40                    caps["ident"].to_string(),
41                ))
42            }
43        }
44    }
45
46    if !remaining_input.is_empty() {
47        return Err(ClimerError::InvalidInput(remaining_input));
48    }
49
50    Ok(builder.build())
51}
52
53fn parse_time_with_format<T, U>(_time: T, _format: U) -> ClimerResult<Time>
54where
55    T: ToString,
56    U: ToString,
57{
58    Err(ClimerError::Unimplemented("--format".to_string()))
59}
60
61#[cfg(test)]
62mod tests;