AkurAI Build
Menu

Public repository / master

AkurAI-Framework / crates/template/src/ast.rs

Latest change d506ed551fac416b6bd5797287d71abc9af1d250 - OLI-211: ==, != and in comparisons in template {% if %} by Ólafur Búi Ólafsson

//! The template AST: what a parsed template is made of.

/// A dotted lookup path into the context, e.g. `user.name` → `["user","name"]`.
pub type Path = Vec<String>;

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Node {
    /// Literal text, emitted verbatim.
    Text(String),
    /// `{{ path }}` (HTML-escaped) or `{{{ path }}}` (raw, `escape = false`).
    Var { path: Path, escape: bool },
    /// `{% if path %} body {% else %} else_body {% endif %}`.
    If {
        cond: Cond,
        body: Vec<Node>,
        else_body: Vec<Node>,
    },
    /// `{% for var in path %} body {% endfor %}` over an array.
    For {
        var: String,
        path: Path,
        body: Vec<Node>,
    },
    /// `{% include "name" %}` — renders another registered template inline.
    Include(String),
    /// `{{ t "key" }}` or `{{ t "key" name=path … }}` — i18n translation lookup.
    ///
    /// The renderer reads `__messages.<key>` from the root context, replaces
    /// `{name}` placeholders by resolving each `(name, path)` arg, then emits
    /// the result (HTML-escaped when `escape = true`).  If the key is absent
    /// the key text itself is emitted.
    Translate {
        key: String,
        /// Named arguments for `{placeholder}` interpolation.  Each element is
        /// `(placeholder_name, context_path)`.
        args: Vec<(String, Path)>,
        /// `true` for `{{ t … }}`, `false` for `{{{ t … }}}`.
        escape: bool,
    },
}

/// One side of a comparison: a context path or a literal.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Operand {
    Path(Path),
    Str(String),
    Int(i64),
}

/// An `{% if %}` condition.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Cond {
    /// `{% if path %}` — truthiness.
    Truthy(Path),
    /// `a == b`
    Eq(Operand, Operand),
    /// `a != b`
    Ne(Operand, Operand),
    /// `needle in haystack` — array membership or substring.
    In(Operand, Operand),
}