vegafusion_core/expression/ast/
binary.rs1use crate::expression::ast::expression::ExpressionTrait;
2use crate::proto::gen::expression::{BinaryExpression, BinaryOperator, Expression};
3use std::fmt::{Display, Formatter};
4
5impl Display for BinaryOperator {
7 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
8 match self {
9 BinaryOperator::Plus => write!(f, "+"),
10 BinaryOperator::Minus => write!(f, "-"),
11 BinaryOperator::Mult => write!(f, "*"),
12 BinaryOperator::Div => write!(f, "/"),
13 BinaryOperator::Mod => write!(f, "%"),
14 BinaryOperator::Equals => write!(f, "=="),
15 BinaryOperator::StrictEquals => write!(f, "==="),
16 BinaryOperator::NotEquals => write!(f, "!="),
17 BinaryOperator::NotStrictEquals => write!(f, "!=="),
18 BinaryOperator::GreaterThan => write!(f, ">"),
19 BinaryOperator::LessThan => write!(f, "<"),
20 BinaryOperator::GreaterThanEqual => write!(f, ">="),
21 BinaryOperator::LessThanEqual => write!(f, "<="),
22 BinaryOperator::BitwiseAnd => write!(f, "&"),
23 BinaryOperator::BitwiseOr => write!(f, "|"),
24 BinaryOperator::BitwiseXor => write!(f, "^"),
25 BinaryOperator::BitwiseShiftLeft => write!(f, "<<"),
26 BinaryOperator::BitwiseShiftRight => write!(f, ">>"),
27 }
28 }
29}
30
31impl BinaryOperator {
32 pub fn infix_binding_power(&self) -> (f64, f64) {
33 match self {
38 BinaryOperator::Plus | BinaryOperator::Minus => (14.0, 14.5),
39 BinaryOperator::Mult | BinaryOperator::Div | BinaryOperator::Mod => (15.0, 15.5),
40 BinaryOperator::GreaterThan
41 | BinaryOperator::LessThan
42 | BinaryOperator::GreaterThanEqual
43 | BinaryOperator::LessThanEqual => (12.0, 12.5),
44 BinaryOperator::Equals
45 | BinaryOperator::StrictEquals
46 | BinaryOperator::NotEquals
47 | BinaryOperator::NotStrictEquals => (11.0, 11.5),
48 BinaryOperator::BitwiseShiftLeft | BinaryOperator::BitwiseShiftRight => (10.0, 10.5),
49 BinaryOperator::BitwiseAnd => (7.0, 7.5),
50 BinaryOperator::BitwiseXor => (6.0, 6.5),
51 BinaryOperator::BitwiseOr => (5.0, 5.5),
52 }
53 }
54}
55
56impl BinaryExpression {
57 pub fn new(lhs: Expression, op: &BinaryOperator, rhs: Expression) -> Self {
58 Self {
59 left: Some(Box::new(lhs)),
60 operator: *op as i32,
61 right: Some(Box::new(rhs)),
62 }
63 }
64
65 pub fn to_operator(&self) -> BinaryOperator {
66 BinaryOperator::try_from(self.operator).unwrap()
67 }
68
69 pub fn infix_binding_power(&self) -> (f64, f64) {
70 self.to_operator().infix_binding_power()
71 }
72
73 pub fn left(&self) -> &Expression {
74 self.left.as_ref().unwrap()
75 }
76
77 pub fn right(&self) -> &Expression {
78 self.right.as_ref().unwrap()
79 }
80}
81
82impl ExpressionTrait for BinaryExpression {
83 fn binding_power(&self) -> (f64, f64) {
84 self.infix_binding_power()
85 }
86}
87
88impl Display for BinaryExpression {
89 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
90 let lhs_bp = self.left.as_ref().unwrap().binding_power();
92 let rhs_bp = self.right.as_ref().unwrap().binding_power();
93 let self_bp = self.binding_power();
94 let lhs_parens = lhs_bp.1 < self_bp.0;
95 let rhs_parens = rhs_bp.0 < self_bp.1;
96
97 if lhs_parens {
99 write!(f, "({})", self.left.as_ref().unwrap())?;
100 } else {
101 write!(f, "{}", self.left.as_ref().unwrap())?;
102 }
103
104 write!(f, " {} ", self.to_operator())?;
105
106 if rhs_parens {
108 write!(f, "({})", self.right.as_ref().unwrap())
109 } else {
110 write!(f, "{}", self.right.as_ref().unwrap())
111 }
112 }
113}