expr/ast/
unary_operator.rs

1use crate::ast::node::Node;
2use crate::ast::unary_operator::UnaryOperator::Not;
3use crate::Rule;
4use crate::Value::Bool;
5use crate::{bail, Result};
6use crate::{Context, Environment, Value};
7use log::trace;
8use pest::iterators::Pair;
9use std::str::FromStr;
10
11#[derive(Debug, Clone, strum::EnumString)]
12pub enum UnaryOperator {
13    #[strum(serialize = "!")]
14    Not,
15}
16
17impl From<Pair<'_, Rule>> for UnaryOperator {
18    fn from(pair: Pair<Rule>) -> Self {
19        trace!("[unary_operator] {pair:?}");
20        match pair.as_str() {
21            "not" => Not,
22            op => UnaryOperator::from_str(op)
23                .unwrap_or_else(|_| unreachable!("Invalid operator {op}")),
24        }
25    }
26}
27
28impl Environment<'_> {
29    pub fn eval_unary_operator(
30        &self,
31        ctx: &Context,
32        operator: UnaryOperator,
33        node: Node,
34    ) -> Result<Value> {
35        let node = self.eval_expr(ctx, node)?;
36        let result = match operator {
37            Not => match node {
38                Bool(b) => Bool(!b),
39                _ => bail!("Invalid operand for operator !"),
40            },
41        };
42
43        Ok(result)
44    }
45}