diff options
-rw-r--r-- | askama_derive/src/generator.rs | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index f40b094..947d88f 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -43,6 +43,8 @@ struct Generator<'a> { super_block: Option<(&'a str, usize)>, // buffer for writable buf_writable: Vec<Writable<'a>>, + // Counter for write! hash named arguments + named: usize, } impl<'a> Generator<'a> { @@ -61,6 +63,7 @@ impl<'a> Generator<'a> { skip_ws: false, super_block: None, buf_writable: vec![], + named: 0, } } @@ -628,6 +631,7 @@ impl<'a> Generator<'a> { } else { let mut buf_format = Buffer::new(0); let mut buf_expr = Buffer::new(buf.indent + 1); + let mut expr_cache = HashMap::with_capacity(self.buf_writable.len()); for s in mem::replace(&mut self.buf_writable, vec![]) { match s { Writable::Lit(s) => { @@ -638,18 +642,31 @@ impl<'a> Generator<'a> { use super::input::EscapeMode::*; let mut expr_buf = Buffer::new(0); let wrapped = self.visit_expr(&mut expr_buf, s); - - buf_format.write("{}"); - buf_expr.write("&"); - buf_expr.write(&match (wrapped, &self.input.escaping) { + let expression = match (wrapped, &self.input.escaping) { (Wrapped, &Html) | (Wrapped, &None) | (Unwrapped, &None) => { - expr_buf.buf + expr_buf.buf.clone() } (Unwrapped, &Html) => { - format!("::askama::MarkupDisplay::from(&{})", expr_buf.buf) + format!( + "::askama::MarkupDisplay::from(&{})", + expr_buf.buf.clone() + ) } + }; + + let id = expr_cache.entry(expression).or_insert_with(|| { + let id = self.named; + self.named += 1; + + buf_expr.write(&format!("a{}=", id)); + buf_expr.write("&"); + buf_expr.write(&expr_buf.buf); + buf_expr.writeln(","); + + id }); - buf_expr.writeln(","); + + buf_format.write(&format!("{{a{}}}", id)); } } } |