forked from Proxmox/proxmox
proxmox-time: move common parse functions to parse_helpers
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
parent
8e0fc66dfe
commit
a104c8fc41
@ -13,6 +13,8 @@ pub use parse_time::*;
|
||||
mod time;
|
||||
pub use time::*;
|
||||
|
||||
pub(crate) mod parse_helpers;
|
||||
|
||||
mod daily_duration;
|
||||
pub use daily_duration::*;
|
||||
|
||||
|
75
proxmox-time/src/parse_helpers.rs
Normal file
75
proxmox-time/src/parse_helpers.rs
Normal file
@ -0,0 +1,75 @@
|
||||
use anyhow::{bail, Error};
|
||||
|
||||
use super::daily_duration::*;
|
||||
|
||||
use nom::{
|
||||
bytes::complete::tag,
|
||||
character::complete::digit1,
|
||||
combinator::{all_consuming, map_res, opt, recognize},
|
||||
error::{ParseError, VerboseError},
|
||||
sequence::{preceded, tuple},
|
||||
};
|
||||
|
||||
pub(crate) type IResult<I, O, E = VerboseError<I>> = Result<(I, O), nom::Err<E>>;
|
||||
|
||||
pub(crate) fn parse_error<'a>(
|
||||
i: &'a str,
|
||||
context: &'static str,
|
||||
) -> nom::Err<VerboseError<&'a str>> {
|
||||
let err = VerboseError { errors: Vec::new() };
|
||||
let err = VerboseError::add_context(i, context, err);
|
||||
nom::Err::Error(err)
|
||||
}
|
||||
|
||||
// Parse a 64 bit unsigned integer
|
||||
pub(crate) fn parse_u64(i: &str) -> IResult<&str, u64> {
|
||||
map_res(recognize(digit1), str::parse)(i)
|
||||
}
|
||||
|
||||
// Parse complete input, generate simple error message (use this for sinple line input).
|
||||
pub(crate) fn parse_complete_line<'a, F, O>(what: &str, i: &'a str, parser: F) -> Result<O, Error>
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_time_comp(max: usize) -> impl Fn(&str) -> IResult<&str, u32> {
|
||||
move |i: &str| {
|
||||
let (i, v) = map_res(recognize(digit1), str::parse)(i)?;
|
||||
if (v as usize) >= max {
|
||||
return Err(parse_error(i, "time value too large"));
|
||||
}
|
||||
Ok((i, v))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_hm_time(i: &str) -> IResult<&str, HmTime> {
|
||||
let (i, (hour, opt_minute)) = tuple((
|
||||
parse_time_comp(24),
|
||||
opt(preceded(tag(":"), parse_time_comp(60))),
|
||||
))(i)?;
|
||||
|
||||
match opt_minute {
|
||||
Some(minute) => Ok((i, HmTime { hour, minute })),
|
||||
None => Ok((i, HmTime { hour, minute: 0 })),
|
||||
}
|
||||
}
|
@ -15,38 +15,7 @@ use nom::{
|
||||
multi::separated_nonempty_list,
|
||||
};
|
||||
|
||||
type IResult<I, O, E = VerboseError<I>> = Result<(I, O), nom::Err<E>>;
|
||||
|
||||
fn parse_error<'a>(i: &'a str, context: &'static str) -> nom::Err<VerboseError<&'a str>> {
|
||||
let err = VerboseError { errors: Vec::new() };
|
||||
let err = VerboseError::add_context(i, context, err);
|
||||
nom::Err::Error(err)
|
||||
}
|
||||
|
||||
// Parse a 64 bit unsigned integer
|
||||
fn parse_u64(i: &str) -> IResult<&str, u64> {
|
||||
map_res(recognize(digit1), str::parse)(i)
|
||||
}
|
||||
|
||||
// Parse complete input, generate simple error message (use this for sinple line input).
|
||||
fn parse_complete_line<'a, F, O>(what: &str, i: &'a str, parser: F) -> Result<O, Error>
|
||||
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),
|
||||
}
|
||||
}
|
||||
use crate::parse_helpers::{parse_complete_line, parse_error, parse_hm_time, parse_time_comp, parse_u64, IResult};
|
||||
|
||||
lazy_static! {
|
||||
static ref TIME_SPAN_UNITS: HashMap<&'static str, f64> = {
|
||||
@ -129,16 +98,6 @@ struct DateSpec {
|
||||
day: Vec<DateTimeValue>,
|
||||
}
|
||||
|
||||
fn parse_time_comp(max: usize) -> impl Fn(&str) -> IResult<&str, u32> {
|
||||
move |i: &str| {
|
||||
let (i, v) = map_res(recognize(digit1), str::parse)(i)?;
|
||||
if (v as usize) >= max {
|
||||
return Err(parse_error(i, "time value too large"));
|
||||
}
|
||||
Ok((i, v))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_weekday(i: &str) -> IResult<&str, WeekDays> {
|
||||
let (i, text) = alpha1(i)?;
|
||||
|
||||
@ -501,16 +460,3 @@ fn parse_daily_duration_incomplete(mut i: &str) -> IResult<&str, DailyDuration>
|
||||
|
||||
Ok((i, duration))
|
||||
}
|
||||
|
||||
fn parse_hm_time(i: &str) -> IResult<&str, HmTime> {
|
||||
|
||||
let (i, (hour, opt_minute)) = tuple((
|
||||
parse_time_comp(24),
|
||||
opt(preceded(tag(":"), parse_time_comp(60))),
|
||||
))(i)?;
|
||||
|
||||
match opt_minute {
|
||||
Some(minute) => Ok((i, HmTime { hour, minute })),
|
||||
None => Ok((i, HmTime { hour, minute: 0})),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user