liquid_core/runtime/
expression.rs

1use std::fmt;
2
3use crate::error::Result;
4use crate::model::Scalar;
5use crate::model::Value;
6use crate::model::ValueCow;
7use crate::model::ValueView;
8
9use super::variable::Variable;
10use super::Runtime;
11
12/// An un-evaluated `Value`.
13#[derive(Debug, Clone, PartialEq)]
14pub enum Expression {
15    /// Un-evaluated.
16    Variable(Variable),
17    /// Evaluated.
18    Literal(Value),
19}
20
21impl Expression {
22    /// Create an expression from a scalar literal.
23    pub fn with_literal<S: Into<Scalar>>(literal: S) -> Self {
24        Expression::Literal(Value::scalar(literal))
25    }
26
27    /// Convert into a literal if possible.
28    pub fn into_literal(self) -> Option<Value> {
29        match self {
30            Expression::Literal(x) => Some(x),
31            Expression::Variable(_) => None,
32        }
33    }
34
35    /// Convert into a variable, if possible.
36    pub fn into_variable(self) -> Option<Variable> {
37        match self {
38            Expression::Literal(_) => None,
39            Expression::Variable(x) => Some(x),
40        }
41    }
42
43    /// Convert to a `Value`.
44    pub fn try_evaluate<'c>(&'c self, runtime: &'c dyn Runtime) -> Option<ValueCow<'c>> {
45        match self {
46            Expression::Literal(ref x) => Some(ValueCow::Borrowed(x)),
47            Expression::Variable(ref x) => {
48                let path = x.try_evaluate(runtime)?;
49                runtime.try_get(&path)
50            }
51        }
52    }
53
54    /// Convert to a `Value`.
55    pub fn evaluate<'c>(&'c self, runtime: &'c dyn Runtime) -> Result<ValueCow<'c>> {
56        let val = match self {
57            Expression::Literal(ref x) => ValueCow::Borrowed(x),
58            Expression::Variable(ref x) => {
59                let path = x.evaluate(runtime)?;
60                runtime.get(&path)?
61            }
62        };
63        Ok(val)
64    }
65}
66
67impl fmt::Display for Expression {
68    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69        match self {
70            Expression::Literal(ref x) => write!(f, "{}", x.source()),
71            Expression::Variable(ref x) => write!(f, "{}", x),
72        }
73    }
74}