diff options
author | René Kijewski <kijewski@library.vetmed.fu-berlin.de> | 2021-07-18 11:42:47 +0200 |
---|---|---|
committer | Dirkjan Ochtman <dirkjan@ochtman.nl> | 2021-11-11 10:05:34 +0100 |
commit | cfe83bcb73b9e0cfd8a2d3151e4cab38327eabea (patch) | |
tree | a4e5b40e033b0d3cfc0d1b48298cb9f9e185d3dd /askama_shared/src/generator.rs | |
parent | f06022c70f2411252ad7ebb8214e0826beaefcf8 (diff) | |
download | askama-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.rs | 37 |
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) } |