vegafusion_core/expression/ast/
unary.rs

1use crate::expression::ast::expression::ExpressionTrait;
2use crate::proto::gen::expression::{Expression, UnaryExpression, UnaryOperator};
3use std::fmt::{Display, Formatter};
4use std::ops::Deref;
5
6impl Display for UnaryOperator {
7    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
8        match self {
9            UnaryOperator::Pos => write!(f, "+"),
10            UnaryOperator::Neg => write!(f, "-"),
11            UnaryOperator::Not => write!(f, "!"),
12        }
13    }
14}
15
16impl UnaryOperator {
17    pub fn unary_binding_power(&self) -> f64 {
18        // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
19        match self {
20            UnaryOperator::Neg | UnaryOperator::Pos | UnaryOperator::Not => 17.0,
21        }
22    }
23}
24
25impl UnaryExpression {
26    pub fn unary_binding_power(&self) -> f64 {
27        self.to_operator().unary_binding_power()
28    }
29
30    pub fn to_operator(&self) -> UnaryOperator {
31        UnaryOperator::try_from(self.operator).unwrap()
32    }
33
34    pub fn new(op: &UnaryOperator, arg: Expression) -> Self {
35        Self {
36            operator: *op as i32,
37            prefix: true,
38            argument: Some(Box::new(arg)),
39        }
40    }
41
42    pub fn argument(&self) -> &Expression {
43        self.argument.as_ref().unwrap()
44    }
45}
46
47impl ExpressionTrait for UnaryExpression {
48    fn binding_power(&self) -> (f64, f64) {
49        let power = self.unary_binding_power();
50        (power, power)
51    }
52}
53
54impl Display for UnaryExpression {
55    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
56        let (_, arg_right_bp) = self.argument.as_ref().unwrap().deref().binding_power();
57        let (self_left_bp, _) = self.binding_power();
58        let op = self.to_operator();
59        if self_left_bp > arg_right_bp {
60            write!(f, "{}({})", op, self.argument.as_ref().unwrap())
61        } else {
62            write!(f, "{}{}", op, self.argument.as_ref().unwrap())
63        }
64    }
65}