Files
gentoo-utils/src/depend/parsers.rs
2025-10-28 12:26:30 +00:00

80 lines
2.4 KiB
Rust

use mon::{Parser, tag, whitespace1};
use crate::{
Parseable,
atom::Atom,
depend::{Conditional, Expr},
useflag::UseFlag,
};
impl<'a> Parseable<'a, &'a str> for Expr {
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 = Expr::parser()
.separated_list(whitespace1(), 1..)
.delimited_by(tag("(").followed_by(whitespace1()), tag(")"))
.preceded_by(Conditional::parser().followed_by(whitespace1()))
.map(|exprs| Expr::OneOf(exprs));
Atom::parser()
.map(|atom| Expr::Atom(atom))
.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 super::*;
#[test]
fn test_expr() {
let it = InputIter::new("flag? ( || ( foo/bar foo/bar ) )");
Expr::parser()
.separated_list(whitespace1(), 0..)
.check_finished(it)
.unwrap();
}
}