Skip to main content

oak_handlebars/ast/
mod.rs

1#![doc = include_str!("readme.md")]
2use core::range::Range;
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6/// Strongly-typed AST root node for Handlebars templates.
7#[derive(Clone, Debug, PartialEq)]
8#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9pub struct HandlebarsRoot {
10    /// List of nodes in the template.
11    pub nodes: Vec<TemplateNode>,
12}
13
14/// Enum representing a template node.
15#[derive(Clone, Debug, PartialEq)]
16#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
17pub enum TemplateNode {
18    /// Plain text content.
19    Content(Content),
20    /// Mustache expression.
21    Mustache(Mustache),
22    /// Block expression.
23    Block(Block),
24    /// Comment.
25    Comment(Comment),
26    /// Partial template reference.
27    Partial(Partial),
28}
29
30/// Node representing plain text content.
31#[derive(Clone, Debug, PartialEq)]
32#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33pub struct Content {
34    /// Text content.
35    pub text: String,
36    /// Span in the source code.
37    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
38    pub span: Range<usize>,
39}
40
41/// Node representing a Mustache expression.
42#[derive(Clone, Debug, PartialEq)]
43#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
44pub struct Mustache {
45    /// Expression content.
46    pub expression: Expression,
47    /// Whether the output is unescaped ({{{...}}}).
48    pub is_unescaped: bool,
49    /// Span in the source code.
50    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
51    pub span: Range<usize>,
52}
53
54/// Node representing a block expression.
55#[derive(Clone, Debug, PartialEq)]
56#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
57pub struct Block {
58    /// Block name.
59    pub name: String,
60    /// List of parameters.
61    pub params: Vec<Expression>,
62    /// Block body content.
63    pub body: Vec<TemplateNode>,
64    /// Inverse block content (else).
65    pub inverse: Option<Vec<TemplateNode>>,
66    /// Span in the source code.
67    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
68    pub span: Range<usize>,
69}
70
71/// Node representing a comment.
72#[derive(Clone, Debug, PartialEq)]
73#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
74pub struct Comment {
75    /// Comment text.
76    pub text: String,
77    /// Span in the source code.
78    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
79    pub span: Range<usize>,
80}
81
82/// Node representing a partial template reference.
83#[derive(Clone, Debug, PartialEq)]
84#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
85pub struct Partial {
86    /// Partial template name.
87    pub name: String,
88    /// List of parameters.
89    pub params: Vec<Expression>,
90    /// Span in the source code.
91    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
92    pub span: Range<usize>,
93}
94
95/// Enum representing an expression.
96#[derive(Clone, Debug, PartialEq)]
97#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
98pub enum Expression {
99    /// Path expression.
100    Path(String),
101    /// Literal
102    Literal(Literal),
103    /// Sub-expression
104    SubExpression(Box<Expression>),
105}
106
107/// Literal enum
108#[derive(Clone, Debug, PartialEq)]
109#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
110pub enum Literal {
111    /// String literal
112    String(String),
113    /// Number literal
114    Number(f64),
115    /// Boolean literal
116    Boolean(bool),
117}