use nom::{error::ParseError, IResult, Parser};
use super::FromInternalError;
pub(crate) fn uncut<I, O, E: ParseError<I>, F: Parser<I, O, E>>(
mut parser: F,
) -> impl FnMut(I) -> IResult<I, O, E> {
move |input: I| match parser.parse(input) {
Err(nom::Err::Failure(e)) => Err(nom::Err::Error(e)),
rest => rest,
}
}
#[allow(dead_code)]
pub(crate) fn map_err<I: Clone, O, E1, E2, F, G>(
mut parser: F,
mut f: G,
) -> impl FnMut(I) -> IResult<I, O, E1>
where
F: nom::Parser<I, O, E1>,
G: FnMut(E1) -> E2,
E1: FromInternalError<I, E2>,
{
move |input: I| {
let i = input.clone();
match parser.parse(i) {
Ok((remainder, value)) => Ok((remainder, value)),
Err(nom::Err::Error(e)) => Err(nom::Err::Error(E1::from_internal_error(input, f(e)))),
Err(nom::Err::Failure(e)) => {
Err(nom::Err::Failure(E1::from_internal_error(input, f(e))))
}
Err(nom::Err::Incomplete(_)) => unreachable!(),
}
}
}
pub(crate) fn cut_with<I, O, E1, E2, F, G>(
mut parser: F,
mut f: G,
) -> impl FnMut(I) -> IResult<I, O, E1>
where
I: Clone,
F: nom::Parser<I, O, E1>,
G: FnMut(E1) -> E2,
E1: FromInternalError<I, E2>,
{
move |input: I| {
let i = input.clone();
match parser.parse(i) {
Ok((remainder, value)) => Ok((remainder, value)),
Err(nom::Err::Error(e) | nom::Err::Failure(e)) => {
Err(nom::Err::Failure(E1::from_internal_error(input, f(e))))
}
Err(nom::Err::Incomplete(_)) => unreachable!(),
}
}
}
#[allow(dead_code)]
pub(crate) fn fail_with<I, O, E1, E2, G>(mut f: G) -> impl FnMut(I) -> IResult<I, O, E1>
where
E1: FromInternalError<I, E2>,
G: FnMut() -> E2,
{
move |input: I| Err(nom::Err::Failure(E1::from_internal_error(input, f())))
}