use nom::character::complete::multispace0;
use nom::combinator::map;
use nom::sequence::delimited;
use nom::error::VerboseError;
pub(crate) type IResult<I, O> = nom::IResult<I, O, VerboseError<I>>;
use nom::{
AsChar,
InputTakeAtPosition,
};
use nom::Parser;
#[macro_export]
#[doc(hidden)]
macro_rules! tuple_separated {
($delim:expr, ($first:expr, $($rest:expr),* $(,)?)) => {{
use nom::sequence::{tuple, preceded};
tuple((
$first,
$(
preceded($delim, $rest),
)*
))
}};
}
pub(crate) fn surrounded_ws<I, Item, O, P: FnMut(I) -> IResult<I, O>>(parser: P) -> impl FnMut(I) -> IResult<I, O>
where
I: InputTakeAtPosition<Item = Item>,
Item: AsChar + Clone,
{
delimited(multispace0, parser, multispace0)
}
pub(crate) fn delimited_ws<I, Item, O1, O2, O3, P1, P2, P3>(p1: P1, p2: P2, p3: P3) -> impl FnMut(I) -> IResult<I, O2>
where
I: InputTakeAtPosition<Item = Item> + Clone,
Item: AsChar + Clone,
P1: FnMut(I) -> IResult<I, O1>,
P2: FnMut(I) -> IResult<I, O2>,
P3: FnMut(I) -> IResult<I, O3>,
{
map(
tuple_separated!(multispace0, (p1, p2, p3)),
|result| result.1
)
}
pub(crate) fn value<I, O1: Clone, O2, F: Parser<I, O2, VerboseError<I>>,>(
parser: F,
val: O1,
) -> impl FnMut(I) -> IResult<I, O1> {
nom::combinator::value(val, parser)
}
#[cfg(test)]
pub(crate) mod tests {
use nom::Err;
use nom::error::{
VerboseError,
VerboseErrorKind,
};
pub(crate) fn err<I, O>(errors: Vec<(I, VerboseErrorKind)>) -> Result<O, Err<VerboseError<I>>> {
Err(Err::Error(VerboseError { errors }))
}
}