use super::*;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Validate<P, F> {
parser: P,
validator: F,
}
impl<P, F> Validate<P, F> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new<'inp, L, O, Ctx>(parser: P, validator: F) -> Self
where
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, ()>,
P: ParseInput<'inp, L, O, Ctx, ()>,
F: FnMut(&O) -> Result<(), <Ctx::Emitter as Emitter<'inp, L, ()>>::Error>,
{
Self { parser, validator }
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn of<'inp, L, O, Ctx, Lang>(parser: P, validator: F) -> Self
where
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
Lang: ?Sized,
P: ParseInput<'inp, L, O, Ctx, Lang>,
F: FnMut(&O) -> Result<(), <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>,
{
Self { parser, validator }
}
}
impl<'inp, P, F, L, O, Ctx, Lang> ParseInput<'inp, L, O, Ctx, Lang> for Validate<P, F>
where
P: ParseInput<'inp, L, O, Ctx, Lang>,
F: FnMut(&O) -> Result<(), <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
Lang: ?Sized,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn parse_input(
&mut self,
input: &mut InputRef<'inp, '_, L, Ctx, Lang>,
) -> Result<O, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error> {
self
.parser
.parse_input(input)
.and_then(|output| (self.validator)(&output).map(|_| output))
}
}
#[cfg(test)]
mod tests {
use crate::lexer::{DummyLexer, DummyToken};
use super::*;
fn assert_validate_parse_impl<'inp>() -> impl Parse<'inp, DummyLexer, Spanned<DummyToken>, ()> {
Parser::new().apply(
Any::new()
.spanned()
.validate(|_tok: &Spanned<DummyToken>| Ok(())),
)
}
fn assert_validate_parse_with_ctx_impl<'inp>()
-> impl Parse<'inp, DummyLexer, Spanned<DummyToken>, ()> {
Parser::with_context(()).apply(
Any::new()
.spanned()
.validate(|_tok: &Spanned<DummyToken>| Ok(())),
)
}
#[test]
fn assert_parse_impl() {
let _ = assert_validate_parse_impl();
let _ = assert_validate_parse_with_ctx_impl();
}
}