use std::fmt;
use crate::parser::{Input, ParseResult, Parser, Span};
use super::{
code::{self, Code},
ParseError,
};
pub fn context<'a, 'b, F, O, M>(mut f: F, msg: M) -> impl FnMut(Input<'a>) -> ParseResult<'a, O>
where
O: 'b,
F: Parser<'a, 'b, O> + 'b,
M: fmt::Display,
{
let msg = msg.to_string();
move |input| {
f.parse(input).map_err(|mut err| {
err.push(
Span::new(input.position(), err.span().end()),
code::ERR_CONTEXT,
msg.to_owned(),
);
err
})
}
}
pub fn context_as<'a, 'b, F, O, M>(
mut f: F,
code: Code,
msg: M,
) -> impl FnMut(Input<'a>) -> ParseResult<'a, O>
where
O: 'b,
F: Parser<'a, 'b, O> + 'b,
M: fmt::Display,
{
let msg = msg.to_string();
move |input| {
f.parse(input).map_err(|mut err| {
err.push(
Span::new(input.position(), err.span().end()),
code,
msg.to_owned(),
);
err
})
}
}
pub fn context_and<'a, 'b, F1, F2, O>(
mut f: F1,
mut g: F2,
) -> impl FnMut(Input<'a>) -> ParseResult<'a, O>
where
O: 'b,
F1: Parser<'a, 'b, O> + 'b,
F2: FnMut(&ParseError) -> (Code, String),
{
move |input| {
f.parse(input).map_err(|mut err| {
let (code, msg) = g(&err);
err.push(Span::new(input.position(), err.span().end()), code, msg);
err
})
}
}