aboutsummaryrefslogtreecommitdiffstats
path: root/askama_derive/src/input.rs
diff options
context:
space:
mode:
authorLibravatar max <gmx.sht@gmail.com>2023-12-11 16:43:16 +0200
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2024-01-17 17:58:53 +0100
commit5cad82f38e800a42717284f20e7e0923add1e32f (patch)
treec58e7220a9e8500b65f3eb116ea12c43bd92a61a /askama_derive/src/input.rs
parent514ae1b24cebb50cad04d0717092a9f890b7a245 (diff)
downloadaskama-5cad82f38e800a42717284f20e7e0923add1e32f.tar.gz
askama-5cad82f38e800a42717284f20e7e0923add1e32f.tar.bz2
askama-5cad82f38e800a42717284f20e7e0923add1e32f.zip
Allow included templates to `extend`, `import`, and `macro`
Signed-off-by: max <gmx.sht@gmail.com>
Diffstat (limited to 'askama_derive/src/input.rs')
-rw-r--r--askama_derive/src/input.rs102
1 files changed, 65 insertions, 37 deletions
diff --git a/askama_derive/src/input.rs b/askama_derive/src/input.rs
index 57fbc04..54facdc 100644
--- a/askama_derive/src/input.rs
+++ b/askama_derive/src/input.rs
@@ -113,46 +113,74 @@ impl TemplateInput<'_> {
let mut check = vec![(self.path.clone(), source)];
while let Some((path, source)) = check.pop() {
let parsed = Parsed::new(source, self.syntax)?;
- for n in parsed.nodes() {
- use Node::*;
- match n {
- Extends(extends) => {
- let extends = self.config.find_template(extends.path, Some(&path))?;
- let dependency_path = (path.clone(), extends.clone());
- if dependency_graph.contains(&dependency_path) {
- return Err(format!(
- "cyclic dependency in graph {:#?}",
- dependency_graph
- .iter()
- .map(|e| format!("{:#?} --> {:#?}", e.0, e.1))
- .collect::<Vec<String>>()
- )
- .into());
+
+ let mut top = true;
+ let mut nested = vec![parsed.nodes()];
+ while let Some(nodes) = nested.pop() {
+ for n in nodes {
+ use Node::*;
+ match n {
+ Extends(extends) if top => {
+ let extends = self.config.find_template(extends.path, Some(&path))?;
+ let dependency_path = (path.clone(), extends.clone());
+ if dependency_graph.contains(&dependency_path) {
+ return Err(format!(
+ "cyclic dependency in graph {:#?}",
+ dependency_graph
+ .iter()
+ .map(|e| format!("{:#?} --> {:#?}", e.0, e.1))
+ .collect::<Vec<String>>()
+ )
+ .into());
+ }
+ dependency_graph.push(dependency_path);
+ let source = get_template_source(&extends)?;
+ check.push((extends, source));
}
- dependency_graph.push(dependency_path);
- let source = get_template_source(&extends)?;
- check.push((extends, source));
- }
- Import(import) => {
- let import = self.config.find_template(import.path, Some(&path))?;
- let source = get_template_source(&import)?;
- check.push((import, source));
+ Macro(m) if top => {
+ nested.push(&m.nodes);
+ }
+ Import(import) if top => {
+ let import = self.config.find_template(import.path, Some(&path))?;
+ let source = get_template_source(&import)?;
+ check.push((import, source));
+ }
+ Include(include) => {
+ let include = self.config.find_template(include.path, Some(&path))?;
+ let source = get_template_source(&include)?;
+ check.push((include, source));
+ }
+ BlockDef(b) => {
+ nested.push(&b.nodes);
+ }
+ If(i) => {
+ for cond in &i.branches {
+ nested.push(&cond.nodes);
+ }
+ }
+ Loop(l) => {
+ nested.push(&l.body);
+ nested.push(&l.else_nodes);
+ }
+ Match(m) => {
+ for arm in &m.arms {
+ nested.push(&arm.nodes);
+ }
+ }
+ Lit(_)
+ | Comment(_)
+ | Expr(_, _)
+ | Call(_)
+ | Extends(_)
+ | Let(_)
+ | Import(_)
+ | Macro(_)
+ | Raw(_)
+ | Continue(_)
+ | Break(_) => {}
}
- If(_)
- | Loop(_)
- | Match(_)
- | BlockDef(_)
- | Include(_)
- | Lit(_)
- | Comment(_)
- | Expr(_, _)
- | Call(_)
- | Let(_)
- | Macro(_)
- | Raw(_)
- | Continue(_)
- | Break(_) => {}
}
+ top = false;
}
map.insert(path, parsed);
}