aboutsummaryrefslogtreecommitdiffstats
path: root/askama_shared/src/generator.rs
diff options
context:
space:
mode:
authorLibravatar René Kijewski <kijewski@library.vetmed.fu-berlin.de>2021-07-18 11:42:47 +0200
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2021-11-11 10:05:34 +0100
commitcfe83bcb73b9e0cfd8a2d3151e4cab38327eabea (patch)
treea4e5b40e033b0d3cfc0d1b48298cb9f9e185d3dd /askama_shared/src/generator.rs
parentf06022c70f2411252ad7ebb8214e0826beaefcf8 (diff)
downloadaskama-cfe83bcb73b9e0cfd8a2d3151e4cab38327eabea.tar.gz
askama-cfe83bcb73b9e0cfd8a2d3151e4cab38327eabea.tar.bz2
askama-cfe83bcb73b9e0cfd8a2d3151e4cab38327eabea.zip
Implement {{loop.cycle(…)}} similar to Jinja
Diffstat (limited to 'askama_shared/src/generator.rs')
-rw-r--r--askama_shared/src/generator.rs37
1 files changed, 30 insertions, 7 deletions
diff --git a/askama_shared/src/generator.rs b/askama_shared/src/generator.rs
index f6d7cca..7500cc7 100644
--- a/askama_shared/src/generator.rs
+++ b/askama_shared/src/generator.rs
@@ -1278,15 +1278,38 @@ impl<'a, S: std::hash::BuildHasher> Generator<'a, S> {
method: &str,
args: &[Expr<'_>],
) -> Result<DisplayWrap, CompileError> {
- if let Expr::Var("self") = obj {
- buf.write("self");
+ if matches!(obj, Expr::Var("loop")) {
+ match method {
+ "cycle" => match args {
+ [arg] => {
+ if matches!(arg, Expr::Array(arr) if arr.is_empty()) {
+ panic!("loop.cycle(…) cannot use an empty array.");
+ }
+ buf.write("({");
+ buf.write("let _cycle = &(");
+ self.visit_expr(buf, arg)?;
+ buf.writeln(");")?;
+ buf.writeln("let _len = _cycle.len();")?;
+ buf.writeln("if _len == 0 {")?;
+ buf.writeln("return ::core::result::Result::Err(::askama::Error::Fmt(::core::fmt::Error));")?;
+ buf.writeln("}")?;
+ buf.writeln("_cycle[_loop_item.index % _len]")?;
+ buf.writeln("})")?;
+ }
+ _ => return Err("loop.cycle(…) expects exactly one argument".into()),
+ },
+ s => return Err(format!("unknown loop method: {:?}", s).into()),
+ }
} else {
- self.visit_expr(buf, obj)?;
+ if let Expr::Var("self") = obj {
+ buf.write("self");
+ } else {
+ self.visit_expr(buf, obj)?;
+ }
+ buf.write(&format!(".{}(", normalize_identifier(method)));
+ self._visit_args(buf, args)?;
+ buf.write(")");
}
-
- buf.write(&format!(".{}(", normalize_identifier(method)));
- self._visit_args(buf, args)?;
- buf.write(")");
Ok(DisplayWrap::Unwrapped)
}