Skip to main content

oak_handlebars/ast/
mod.rs

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