1#![allow(clippy::many_single_char_names, clippy::cognitive_complexity)]
2use std::ops::{Deref, DerefMut};
3use std::str;
4
5use serde::{Deserialize, Deserializer};
6use syn::parse::{Parse, ParseBuffer};
7
8#[macro_use]
9mod strnom;
10
11#[cfg(test)]
12mod test;
13
14mod error;
15mod expr_list;
16mod parse;
17mod pre_partials;
18pub mod source_map;
19mod stmt_local;
20
21use crate::source_map::S;
22
23pub use self::{
24 error::{emitter, ErrorMessage},
25 parse::*,
26 pre_partials::parse_partials,
27 stmt_local::StmtLocal,
28 strnom::Cursor,
29};
30
31pub type Ws = (bool, bool);
32
33#[derive(Debug, PartialEq, Clone, Deserialize)]
34pub struct Local(#[serde(deserialize_with = "de_local")] syn::Local);
35
36impl Deref for Local {
37 type Target = syn::Local;
38
39 fn deref(&self) -> &Self::Target {
40 &self.0
41 }
42}
43
44impl DerefMut for Local {
45 fn deref_mut(&mut self) -> &mut Self::Target {
46 &mut self.0
47 }
48}
49
50impl AsRef<syn::Local> for Local {
51 fn as_ref(&self) -> &syn::Local {
52 &self.0
53 }
54}
55
56impl AsMut<syn::Local> for Local {
57 fn as_mut(&mut self) -> &mut syn::Local {
58 &mut self.0
59 }
60}
61
62fn de_local<'de, D>(deserializer: D) -> Result<syn::Local, D::Error>
63where
64 D: Deserializer<'de>,
65{
66 <&str>::deserialize(deserializer).and_then(|x| {
67 syn::parse_str::<StmtLocal>(x)
68 .map(Into::into)
69 .map_err(|_| serde::de::Error::custom("Parse error"))
70 })
71}
72
73impl Parse for Local {
74 fn parse(input: &ParseBuffer<'_>) -> syn::Result<Self> {
75 Ok(Local(input.parse::<StmtLocal>()?.into()))
76 }
77}
78
79#[derive(Debug, PartialEq, Clone, Deserialize)]
80pub struct Expr(#[serde(deserialize_with = "de_expr")] syn::Expr);
81
82impl Deref for Expr {
83 type Target = syn::Expr;
84
85 fn deref(&self) -> &Self::Target {
86 &self.0
87 }
88}
89
90impl DerefMut for Expr {
91 fn deref_mut(&mut self) -> &mut Self::Target {
92 &mut self.0
93 }
94}
95
96impl AsRef<syn::Expr> for Expr {
97 fn as_ref(&self) -> &syn::Expr {
98 &self.0
99 }
100}
101
102impl AsMut<syn::Expr> for Expr {
103 fn as_mut(&mut self) -> &mut syn::Expr {
104 &mut self.0
105 }
106}
107
108fn de_expr<'de, D>(deserializer: D) -> Result<syn::Expr, D::Error>
109where
110 D: Deserializer<'de>,
111{
112 <&str>::deserialize(deserializer)
113 .and_then(|x| syn::parse_str(x).map_err(|_| serde::de::Error::custom("Parse error")))
114}
115
116impl Parse for Expr {
117 fn parse(input: &ParseBuffer<'_>) -> syn::Result<Self> {
118 Ok(Expr(input.parse()?))
119 }
120}
121
122pub type SExpr = S<Box<Expr>>;
123pub type SLocal = S<Box<Local>>;
124pub type SNode<'a> = S<Node<'a>>;
125pub type SStr<'a> = S<&'a str>;
126pub type SVExpr = S<Vec<Expr>>;
127
128#[derive(Debug, PartialEq, Clone, Deserialize)]
129pub struct Partial<'a>(pub Ws, #[serde(borrow)] pub SStr<'a>, pub SVExpr);
130
131#[derive(Debug, PartialEq, Clone, Deserialize)]
132pub struct PartialBlock<'a>(
133 pub (Ws, Ws),
134 #[serde(borrow)] pub SStr<'a>,
135 pub SVExpr,
136 #[serde(borrow)] pub Vec<SNode<'a>>,
137);
138
139#[derive(Debug, PartialEq, Clone, Deserialize)]
141pub enum Node<'a> {
142 Comment(#[serde(borrow)] &'a str),
143 Expr(Ws, SExpr),
144 AtHelper(Ws, AtHelperKind, SVExpr),
145 RExpr(Ws, SExpr),
146 Helper(#[serde(borrow)] Box<Helper<'a>>),
147 Lit(
148 #[serde(borrow)] &'a str,
149 #[serde(borrow)] SStr<'a>,
150 #[serde(borrow)] &'a str,
151 ),
152 Local(SLocal),
153 Partial(#[serde(borrow)] Partial<'a>),
154 PartialBlock(#[serde(borrow)] PartialBlock<'a>),
155 Block(Ws),
156 Raw(
157 (Ws, Ws),
158 #[serde(borrow)] &'a str,
159 #[serde(borrow)] SStr<'a>,
160 #[serde(borrow)] &'a str,
161 ),
162 Safe(Ws, SExpr),
163 Error(SVExpr),
164}
165
166pub(crate) const JSON: &str = "json";
167pub(crate) const JSON_PRETTY: &str = "json_pretty";
168#[derive(Debug, PartialEq, Clone, Deserialize)]
169pub enum AtHelperKind {
170 Json,
171 JsonPretty,
172}
173
174#[derive(Debug, PartialEq, Clone, Deserialize)]
175pub enum Helper<'a> {
176 Each((Ws, Ws), SExpr, #[serde(borrow)] Vec<SNode<'a>>),
177 If(
178 ((Ws, Ws), SExpr, Vec<SNode<'a>>),
179 Vec<(Ws, SExpr, Vec<SNode<'a>>)>,
180 Option<(Ws, Vec<SNode<'a>>)>,
181 ),
182 With((Ws, Ws), SExpr, #[serde(borrow)] Vec<SNode<'a>>),
183 Unless((Ws, Ws), SExpr, #[serde(borrow)] Vec<SNode<'a>>),
184 Defined(
186 (Ws, Ws),
187 #[serde(borrow)] &'a str,
188 SExpr,
189 #[serde(borrow)] Vec<SNode<'a>>,
190 ),
191}