use core::marker::PhantomData;
use super::*;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Then<F, T> {
parser: F,
then: T,
}
impl<F, T> Then<F, T> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(parser: F, then: T) -> Self {
Self { parser, then }
}
}
impl<'inp, F, T, L, O, U, Ctx, Lang> ParseInput<'inp, L, (O, U), Ctx, Lang> for Then<F, T>
where
F: ParseInput<'inp, L, O, Ctx, Lang>,
T: ParseInput<'inp, L, U, Ctx, Lang>,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn parse_input(
&mut self,
input: &mut InputRef<'inp, '_, L, Ctx, Lang>,
) -> Result<(O, U), <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error> {
let a = self.parser.parse_input(input)?;
let b = self.then.parse_input(input)?;
Ok((a, b))
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct IgnoreThen<F, G, O1> {
first: F,
second: G,
_marker: PhantomData<O1>,
}
impl<F, G, O1> IgnoreThen<F, G, O1> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(first: F, second: G) -> Self {
Self {
first,
second,
_marker: PhantomData,
}
}
}
impl<'inp, F, G, L, O1, O2, Ctx, Lang> ParseInput<'inp, L, O2, Ctx, Lang> for IgnoreThen<F, G, O1>
where
F: ParseInput<'inp, L, O1, Ctx, Lang>,
G: ParseInput<'inp, L, O2, Ctx, Lang>,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn parse_input(
&mut self,
input: &mut InputRef<'inp, '_, L, Ctx, Lang>,
) -> Result<O2, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error> {
let _ = self.first.parse_input(input)?;
self.second.parse_input(input)
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ThenIgnore<F, G, O2> {
first: F,
second: G,
_marker: PhantomData<O2>,
}
impl<F, G, O2> ThenIgnore<F, G, O2> {
#[cfg_attr(not(tarpaulin), inline(always))]
pub const fn new(first: F, second: G) -> Self {
Self {
first,
second,
_marker: PhantomData,
}
}
}
impl<'inp, F, G, L, O1, O2, Ctx, Lang> ParseInput<'inp, L, O1, Ctx, Lang> for ThenIgnore<F, G, O2>
where
F: ParseInput<'inp, L, O1, Ctx, Lang>,
G: ParseInput<'inp, L, O2, Ctx, Lang>,
L: Lexer<'inp>,
Ctx: ParseContext<'inp, L, Lang>,
{
#[cfg_attr(not(tarpaulin), inline(always))]
fn parse_input(
&mut self,
input: &mut InputRef<'inp, '_, L, Ctx, Lang>,
) -> Result<O1, <Ctx::Emitter as Emitter<'inp, L, Lang>>::Error> {
let first_result = self.first.parse_input(input)?;
self.second.parse_input(input).map(|_| first_result)
}
}
#[cfg(test)]
mod tests {
use crate::lexer::{DummyLexer, DummyToken};
use super::*;
fn assert_ignore_then_parse_impl<'inp>() -> impl Parse<'inp, DummyLexer, DummyToken, ()> {
Parser::new().apply(Any::new().ignore_then(Any::new()))
}
fn assert_then_ignore_parse_impl<'inp>() -> impl Parse<'inp, DummyLexer, DummyToken, ()> {
Parser::new().apply(Any::new().then_ignore(Any::new()))
}
#[test]
fn assert_parse_impl() {
let _ = assert_ignore_then_parse_impl();
let _ = assert_then_ignore_parse_impl();
}
}