fix: parse repeated condition negations

This commit is contained in:
immanuwell 2026-05-08 20:10:22 +04:00 committed by sxyazi
parent 92b9ea3794
commit f8705f00d3
No known key found for this signature in database

View file

@ -72,7 +72,10 @@ impl Condition {
let op = ConditionOp::new(token); let op = ConditionOp::new(token);
match op { match op {
ConditionOp::Or | ConditionOp::And | ConditionOp::Not => { ConditionOp::Or | ConditionOp::And | ConditionOp::Not => {
while matches!(stack.last(), Some(last) if last.prec() >= op.prec()) { while matches!(
stack.last(),
Some(last) if last.prec() > op.prec() || (op != ConditionOp::Not && last.prec() == op.prec())
) {
output.push(stack.pop().unwrap()); output.push(stack.pop().unwrap());
} }
stack.push(op); stack.push(op);
@ -129,3 +132,21 @@ impl Condition {
if stack.len() == 1 { Some(stack[0]) } else { None } if stack.len() == 1 { Some(stack[0]) } else { None }
} }
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_condition_not() -> anyhow::Result<()> {
let cond: Condition = "!!dir".parse()?;
assert!(cond.eval(|s| s == "dir").unwrap());
assert!(!cond.eval(|_| false).unwrap());
let cond: Condition = "!!!dir".parse()?;
assert!(!cond.eval(|s| s == "dir").unwrap());
assert!(cond.eval(|_| false).unwrap());
Ok(())
}
}