vegafusion_core/expression/ast/
object.rs

1use crate::expression::ast::expression::ExpressionTrait;
2use crate::proto::gen::expression::literal::Value;
3use crate::proto::gen::expression::property::Key;
4use crate::proto::gen::expression::{Expression, Identifier, Literal, ObjectExpression, Property};
5use std::fmt::{Display, Formatter};
6
7use crate::error::{Result, VegaFusionError};
8
9impl Display for Key {
10    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
11        match self {
12            Key::Literal(v) => write!(f, "{}", v.value.as_ref().unwrap()),
13            Key::Identifier(v) => write!(f, "{v}"),
14        }
15    }
16}
17
18impl Key {
19    pub fn new_literal(key: Literal) -> Self {
20        Key::Literal(key)
21    }
22
23    pub fn new_identifier(key: Identifier) -> Self {
24        Self::Identifier(key)
25    }
26
27    // Get string for property for use as object key. Strings should not be quoted
28    pub fn to_object_key_string(&self) -> String {
29        match self {
30            Key::Literal(v) => match v.value.as_ref().unwrap() {
31                Value::String(s) => s.clone(),
32                _ => v.to_string(),
33            },
34            Key::Identifier(v) => v.name.clone(),
35        }
36    }
37}
38
39impl Property {
40    pub fn try_new(key: Expression, value: Expression) -> Result<Self> {
41        if let Ok(identifier) = key.as_identifier() {
42            Ok(Self::new_identifier(identifier.clone(), value))
43        } else if let Ok(literal) = key.as_literal() {
44            Ok(Self::new_literal(literal.clone(), value))
45        } else {
46            Err(VegaFusionError::internal(
47                "Object key must be an identifier or a literal value",
48            ))
49        }
50    }
51
52    pub fn new_literal(key: Literal, value: Expression) -> Self {
53        Self {
54            value: Some(value),
55            key: Some(Key::new_literal(key)),
56            kind: "init".to_string(),
57        }
58    }
59
60    pub fn new_identifier(key: Identifier, value: Expression) -> Self {
61        Self {
62            value: Some(value),
63            key: Some(Key::new_identifier(key)),
64            kind: "init".to_string(),
65        }
66    }
67
68    pub fn key(&self) -> &Key {
69        self.key.as_ref().unwrap()
70    }
71
72    pub fn value(&self) -> &Expression {
73        self.value.as_ref().unwrap()
74    }
75}
76
77impl Display for Property {
78    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
79        write!(f, "{}: {}", self.key(), self.value())
80    }
81}
82
83impl ObjectExpression {
84    pub fn new(properties: Vec<Property>) -> Self {
85        Self { properties }
86    }
87}
88
89impl ExpressionTrait for ObjectExpression {}
90
91impl Display for ObjectExpression {
92    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
93        let property_strings: Vec<String> = self.properties.iter().map(|p| p.to_string()).collect();
94        let property_csv = property_strings.join(", ");
95        write!(f, "{{{property_csv}}}")
96    }
97}