Skip to main content

shrub_core/
tests.rs

1//! Shell test conditional expressions
2
3use crate::{ExecutionParameters, Shell, error, extendedtests, extensions};
4
5/// Evaluate the given test expression within the provided shell and
6/// execution context. Returns true if the expression evaluates to true,
7/// false otherwise.
8///
9/// # Arguments
10///
11/// * `expr` - The test expression to evaluate.
12/// * `shell` - The shell context in which to evaluate the expression.
13/// * `params` - The execution parameters to use during evaluation.
14///
15/// # Errors
16///
17/// Returns [`error::ErrorKind::Unimplemented`] for unsupported predicates, an
18/// [`error::ErrorKind::IoError`] if a file predicate cannot read metadata, or
19/// any other error from evaluating a sub-expression.
20pub fn eval_expr(
21    expr: &shrub_parser::ast::TestExpr,
22    shell: &mut Shell<impl extensions::ShellExtensions>,
23    params: &ExecutionParameters,
24) -> Result<bool, error::Error> {
25    match expr {
26        shrub_parser::ast::TestExpr::False => Ok(false),
27        shrub_parser::ast::TestExpr::Literal(s) => Ok(!s.is_empty()),
28        shrub_parser::ast::TestExpr::And(left, right) => {
29            Ok(eval_expr(left, shell, params)? && eval_expr(right, shell, params)?)
30        }
31        shrub_parser::ast::TestExpr::Or(left, right) => {
32            Ok(eval_expr(left, shell, params)? || eval_expr(right, shell, params)?)
33        }
34        shrub_parser::ast::TestExpr::Not(expr) => Ok(!eval_expr(expr, shell, params)?),
35        shrub_parser::ast::TestExpr::Parenthesized(expr) => eval_expr(expr, shell, params),
36        shrub_parser::ast::TestExpr::UnaryTest(op, operand) => {
37            extendedtests::apply_unary_predicate_to_str(op, operand, shell, params)
38        }
39        shrub_parser::ast::TestExpr::BinaryTest(op, left, right) => {
40            extendedtests::apply_binary_predicate_to_strs(op, left.as_str(), right.as_str(), shell)
41        }
42    }
43}