1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
use crate::helpers::digits::{dec_digits_2, dec_digits_9}; use chrono::NaiveTime; use nom::{ character::complete::char, combinator::{map_opt, opt}, sequence::{preceded, tuple}, IResult, }; pub(crate) fn time(i: &str) -> IResult<&str, NaiveTime> { map_opt( tuple(( dec_digits_2, preceded(char(':'), dec_digits_2), preceded(char(':'), dec_digits_2), opt(preceded(char('.'), dec_digits_9)), )), |(hours, minutes, seconds, nanoseconds)| { NaiveTime::from_hms_nano_opt( hours.into(), minutes.into(), seconds.into(), nanoseconds.unwrap_or(0).into(), ) }, )(i) } #[test] fn it_should_parse_simple_time() { assert_eq!(time("12:03:12"), Ok(("", NaiveTime::from_hms(12, 3, 12)))); } #[test] fn it_should_parse_time_with_nanoseconds() { assert_eq!( time("13:01:01.123456789"), Ok(("", NaiveTime::from_hms_nano(13, 1, 1, 123456789))) ); } #[test] fn it_should_fail_given_time_is_out_of_range() { let invalid = ["25:00:00", "01:60:00", "01:59:60"]; for &v in &invalid { assert!(time(v).is_err()); } }