vegafusion_core/expression/ast/
member.rs

1use crate::error::Result;
2use crate::expression::ast::expression::ExpressionTrait;
3use crate::proto::gen::expression::{Expression, MemberExpression};
4use std::fmt::{Display, Formatter};
5
6impl MemberExpression {
7    pub fn new_computed(object: Expression, property: Expression) -> Self {
8        Self {
9            object: Some(Box::new(object)),
10            property: Some(Box::new(property)),
11            computed: true,
12        }
13    }
14
15    pub fn new_static(object: Expression, property: Expression) -> Result<Self> {
16        // Make sure property is an identifier
17        property.as_identifier()?;
18        Ok(Self {
19            object: Some(Box::new(object)),
20            property: Some(Box::new(property)),
21            computed: false,
22        })
23    }
24
25    pub fn member_binding_power() -> (f64, f64) {
26        // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
27        //  - left-to-right operators have larger number to the right
28        //  - right-to-left have larger number to the left
29        (20.0, 20.5)
30    }
31
32    pub fn property(&self) -> &Expression {
33        self.property.as_ref().unwrap()
34    }
35
36    pub fn object(&self) -> &Expression {
37        self.object.as_ref().unwrap()
38    }
39}
40
41impl ExpressionTrait for MemberExpression {
42    fn binding_power(&self) -> (f64, f64) {
43        Self::member_binding_power()
44    }
45}
46
47impl Display for MemberExpression {
48    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
49        let object_rhs_bp = self.object.as_ref().unwrap().binding_power().1;
50
51        // Write object, using binding power to determine whether to wrap it in parenthesis
52        if object_rhs_bp < Self::member_binding_power().0 {
53            write!(f, "({})", self.object.as_ref().unwrap())?;
54        } else {
55            write!(f, "{}", self.object.as_ref().unwrap())?;
56        }
57
58        // Write property
59        if self.computed {
60            write!(f, "[{}]", self.property.as_ref().unwrap())
61        } else {
62            write!(f, ".{}", self.property.as_ref().unwrap())
63        }
64    }
65}