liquid_interpreter/
expression.rs

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