use mon::{Parser, tag, whitespace1}; use crate::{ Parseable, depend::{Conditional, Expr}, useflag::UseFlag, }; impl<'a, T> Parseable<'a, &'a str> for Expr where T: Parseable<'a, &'a str>, { type Parser = impl Parser<&'a str, Output = Self>; fn parser() -> Self::Parser { |it| { let all_of_group = Expr::parser() .separated_list(whitespace1(), 1..) .delimited_by(tag("(").followed_by(whitespace1()), tag(")")) .map(|exprs| Expr::AllOf(exprs)); let any_of_group = Expr::parser() .separated_list(whitespace1(), 1..) .delimited_by(tag("(").followed_by(whitespace1()), tag(")")) .preceded_by(tag("||").followed_by(whitespace1())) .map(|exprs| Expr::AnyOf(exprs)); let one_of_group = Expr::parser() .separated_list(whitespace1(), 1..) .delimited_by(tag("(").followed_by(whitespace1()), tag(")")) .preceded_by(tag("^^").followed_by(whitespace1())) .map(|exprs| Expr::OneOf(exprs)); let conditional_group = Conditional::parser() .followed_by(whitespace1()) .and( Expr::parser() .separated_list(whitespace1(), 1..) .delimited_by(tag("(").followed_by(whitespace1()), tag(")")), ) .map(|(conditional, exprs)| Expr::ConditionalGroup(conditional, exprs)); T::parser() .map(|e| Expr::Element(e)) .or(conditional_group) .or(any_of_group) .or(all_of_group) .or(one_of_group) .parse(it) } } } impl<'a> Parseable<'a, &'a str> for Conditional { type Parser = impl Parser<&'a str, Output = Self>; fn parser() -> Self::Parser { UseFlag::parser() .preceded_by(tag("!")) .followed_by(tag("?")) .map(|flag| Conditional::Negative(flag)) .or(UseFlag::parser() .followed_by(tag("?")) .map(|flag| Conditional::Positive(flag))) } } #[cfg(test)] mod test { use mon::input::InputIter; use crate::atom::Atom; use super::*; #[test] fn test_expr() { let it = InputIter::new("flag? ( || ( foo/bar foo/bar ) )"); Expr::::parser() .separated_list(whitespace1(), 0..) .check_finished(it) .unwrap(); } }