aboutsummaryrefslogtreecommitdiffstats
path: root/askama_shared/src/generator.rs
diff options
context:
space:
mode:
authorLibravatar René Kijewski <kijewski@library.vetmed.fu-berlin.de>2021-06-29 15:15:18 +0200
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2021-07-01 10:24:32 +0200
commit06d2eee4a0cd9070444d9d166044de9ffe6ca330 (patch)
tree3b5976ea68f4b94517e4d2070a280df111c2cc83 /askama_shared/src/generator.rs
parent5afabbc7e3ae7146d14c95735850edfd7f705421 (diff)
downloadaskama-06d2eee4a0cd9070444d9d166044de9ffe6ca330.tar.gz
askama-06d2eee4a0cd9070444d9d166044de9ffe6ca330.tar.bz2
askama-06d2eee4a0cd9070444d9d166044de9ffe6ca330.zip
Implement "if let" statement
Diffstat (limited to 'askama_shared/src/generator.rs')
-rw-r--r--askama_shared/src/generator.rs39
1 files changed, 27 insertions, 12 deletions
diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs
index 24a4a71..fc94977 100644
--- a/askama_shared/src/generator.rs
+++ b/askama_shared/src/generator.rs
@@ -3,7 +3,8 @@ use crate::filters;
use crate::heritage::{Context, Heritage};
use crate::input::{Source, TemplateInput};
use crate::parser::{
- parse, Cond, Expr, MatchParameter, MatchParameters, MatchVariant, Node, Target, When, Ws,
+ parse, Cond, CondTest, Expr, MatchParameter, MatchParameters, MatchVariant, Node, Target, When,
+ Ws,
};
use proc_macro2::Span;
@@ -483,23 +484,38 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> {
self.locals.pop();
}
+ self.locals.push();
let mut arm_size = 0;
- if let Some(expr) = cond {
+ if let Some(CondTest { target, expr }) = cond {
if i == 0 {
buf.write("if ");
} else {
buf.dedent()?;
buf.write("} else if ");
}
- // The following syntax `*(&(...) as &bool)` is used to
- // trigger Rust's automatic dereferencing, to coerce
- // e.g. `&&&&&bool` to `bool`. First `&(...) as &bool`
- // coerces e.g. `&&&bool` to `&bool`. Then `*(&bool)`
- // finally dereferences it to `bool`.
- buf.write("*(&(");
- let expr_code = self.visit_expr_root(expr)?;
- buf.write(&expr_code);
- buf.write(") as &bool)");
+
+ if let Some((variant, params)) = target {
+ let mut expr_buf = Buffer::new(0);
+ self.visit_expr(&mut expr_buf, expr)?;
+ buf.write("let ");
+ self.visit_match_variant(buf, variant);
+ if let Some(params) = params {
+ self.visit_match_params(buf, params);
+ }
+ buf.write(" = &(");
+ buf.write(&expr_buf.buf);
+ buf.write(")");
+ } else {
+ // The following syntax `*(&(...) as &bool)` is used to
+ // trigger Rust's automatic dereferencing, to coerce
+ // e.g. `&&&&&bool` to `bool`. First `&(...) as &bool`
+ // coerces e.g. `&&&bool` to `&bool`. Then `*(&bool)`
+ // finally dereferences it to `bool`.
+ buf.write("*(&(");
+ let expr_code = self.visit_expr_root(expr)?;
+ buf.write(&expr_code);
+ buf.write(") as &bool)");
+ }
} else {
buf.dedent()?;
buf.write("} else");
@@ -507,7 +523,6 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> {
}
buf.writeln(" {")?;
- self.locals.push();
arm_size += self.handle(ctx, nodes, buf, AstLevel::Nested)?;
arm_sizes.push(arm_size);