pdk_script/
expression.rs

1// Copyright (c) 2025, Salesforce, Inc.,
2// All rights reserved.
3// For full license text, see the LICENSE.txt file
4
5use std::fmt::{Display, Formatter};
6
7use serde::de::Visitor;
8use serde::{Deserialize, Deserializer};
9
10use pel::expression::Expression as PelExpression;
11use pel::parser::{Parser, ParsingUnitError};
12
13/// An evaluable expression.
14#[derive(PartialEq, Clone, Debug)]
15pub struct Expression {
16    pub(crate) source: Option<String>,
17    pub(crate) expression: PelExpression,
18}
19
20impl Expression {
21    fn new(expression: PelExpression) -> Self {
22        Self {
23            source: None,
24            expression,
25        }
26    }
27
28    pub(crate) fn with_source(mut self, source: Option<String>) -> Self {
29        self.source = source;
30        self
31    }
32}
33
34impl Display for Expression {
35    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
36        let source = self.source.as_deref().unwrap_or_default();
37        f.write_fmt(format_args!("#[{source}]"))
38    }
39}
40
41impl<'de> Deserialize<'de> for Expression {
42    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
43    where
44        D: Deserializer<'de>,
45    {
46        struct ResolverVisitor;
47
48        impl Visitor<'_> for ResolverVisitor {
49            type Value = Expression;
50
51            fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
52                formatter.write_str("PEL Expression")
53            }
54
55            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
56            where
57                E: serde::de::Error,
58            {
59                let effective_value = if value.is_empty() {
60                    r##"P[[":null", "0-4"], "#[null]"]"##
61                } else {
62                    value
63                };
64
65                let (expression, source) =
66                    Parser::new()
67                        .parse_unit(effective_value)
68                        .map_err(|error| match error {
69                            ParsingUnitError::InvalidContainer => serde::de::Error::invalid_type(
70                                serde::de::Unexpected::Str(value),
71                                &self,
72                            ),
73                            _ => serde::de::Error::custom(format_args!(
74                                "Unexpected error when parsing expression '{value}': {error}"
75                            )),
76                        })?;
77
78                Ok(Expression::new(expression).with_source(source))
79            }
80        }
81
82        deserializer.deserialize_str(ResolverVisitor)
83    }
84}