use core::marker::PhantomData;
use super::*;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct FilterMap<P, F, O> {
parser: P,
mapper: F,
_marker: PhantomData<O>,
}
impl<P, F, O> FilterMap<P, F, O> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new<'inp, L, U, Ctx>(parser: P, filter: F) -> Self
where
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, ()>,
P: ParseInput<'inp, L, O, Ctx, ()>,
F: FnMut(O) -> Result<U, <Ctx::Emitter as Emitter<'inp, L, ()>>::Error>,
{
Self::of(parser, filter)
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn of<'inp, L, U, Ctx, Lang>(parser: P, filter: F) -> Self
where
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
Lang: ?Sized,
P: ParseInput<'inp, L, O, Ctx, Lang>,
F: FnMut(O) -> Result<U, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error>,
{
Self {
parser,
mapper: filter,
_marker: PhantomData,
}
}
}
impl<'inp, P, F, L, O, U, Ctx, Lang> ParseInput<'inp, L, U, Ctx, Lang> for FilterMap<P, F, O>
where
P: ParseInput<'inp, L, O, Ctx, Lang>,
F: FnMut(O) -> Result<U, <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<U, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error> {
self.parser.parse_input(input).and_then(&mut self.mapper)
}
}
#[cfg(test)]
mod tests {
use crate::lexer::{DummyLexer, DummyToken};
use super::*;
fn assert_filter_map_parse_impl<'inp>() -> impl Parse<'inp, DummyLexer, (), ()> {
Parser::new().apply(Any::new().filter_map(|_tok: DummyToken| Ok(())))
}
fn assert_filter_map_parse_with_ctx_impl<'inp>() -> impl Parse<'inp, DummyLexer, (), ()> {
Parser::with_context(()).apply(Any::new().filter_map(|_tok: DummyToken| Ok(())))
}
#[test]
fn assert_parse_impl() {
let _ = assert_filter_map_parse_impl();
let _ = assert_filter_map_parse_with_ctx_impl();
}
}