diff --git a/src/tools/nom.rs b/src/tools/nom.rs index 0b0fe816..ca03c5d7 100644 --- a/src/tools/nom.rs +++ b/src/tools/nom.rs @@ -41,6 +41,7 @@ pub fn parse_u64(i: &str) -> IResult<&str, u64> { map_res(recognize(digit1), str::parse)(i) } +/// Parse complete input, generate vervose error message with line numbers pub fn parse_complete<'a, F, O>(what: &str, i: &'a str, parser: F) -> Result where F: Fn(&'a str) -> IResult<&'a str, O>, { @@ -56,3 +57,23 @@ pub fn parse_complete<'a, F, O>(what: &str, i: &'a str, parser: F) -> Result(what: &str, i: &'a str, parser: F) -> Result + where F: Fn(&'a str) -> IResult<&'a str, O>, +{ + match all_consuming(parser)(i) { + Err(nom::Err::Error(VerboseError { errors })) | + Err(nom::Err::Failure(VerboseError { errors })) => { + if errors.is_empty() { + bail!("unable to parse {}", what); + } else { + bail!("unable to parse {} at '{}' - {:?}", what, errors[0].0, errors[0].1); + } + } + Err(err) => { + bail!("unable to parse {} - {}", what, err); + } + Ok((_, data)) => Ok(data), + } +} diff --git a/src/tools/systemd/parse_time.rs b/src/tools/systemd/parse_time.rs index 00bcbfba..b1cbc38d 100644 --- a/src/tools/systemd/parse_time.rs +++ b/src/tools/systemd/parse_time.rs @@ -1,18 +1,18 @@ use std::collections::HashMap; -use anyhow::{bail, Error}; +use anyhow::{Error}; use lazy_static::lazy_static; use super::time::*; use crate::tools::nom::{ - parse_complete, parse_u64, parse_error, IResult, + parse_complete_line, parse_u64, parse_error, IResult, }; use nom::{ error::{context}, bytes::complete::{tag, take_while1}, - combinator::{map_res, all_consuming, opt, recognize}, + combinator::{map_res, opt, recognize}, sequence::{pair, preceded, tuple}, character::complete::{alpha1, space0, digit1}, multi::separated_nonempty_list, @@ -184,7 +184,7 @@ fn parse_time_spec(i: &str) -> IResult<&str, (Vec, Vec Result { - parse_complete("calendar event", i, parse_calendar_event_incomplete) + parse_complete_line("calendar event", i, parse_calendar_event_incomplete) } fn parse_calendar_event_incomplete(mut i: &str) -> IResult<&str, CalendarEvent> { @@ -269,10 +269,7 @@ fn parse_time_unit(i: &str) -> IResult<&str, &str> { pub fn parse_time_span(i: &str) -> Result { - match all_consuming(parse_time_span_incomplete)(i) { - Err(err) => bail!("unable to parse time span: {}", err), - Ok((_, ts)) => Ok(ts), - } + parse_complete_line("time span", i, parse_time_span_incomplete) } fn parse_time_span_incomplete(mut i: &str) -> IResult<&str, TimeSpan> {