Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove unnecessary allocs of discarded content #1055

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions askama_derive/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ impl<'a> Generator<'a> {
buf.write(CRATE);
buf.writeln("::Result<()> {")?;

buf.discard = self.buf_writable.discard;
// Make sure the compiler understands that the generated code depends on the template files.
for path in self.contexts.keys() {
// Skip the fake path of templates defined in rust source.
Expand All @@ -113,6 +114,7 @@ impl<'a> Generator<'a> {
} else {
self.handle(ctx, ctx.nodes, buf, AstLevel::Top)
}?;
buf.discard = false;

self.flush_ws(Ws(None, None));
buf.write(CRATE);
Expand Down Expand Up @@ -363,7 +365,7 @@ impl<'a> Generator<'a> {
}

if let Some(target) = target {
let mut expr_buf = Buffer::new(0);
let mut expr_buf = Buffer::from_buf_parameters(buf, 0);
buf.write("let ");
// If this is a chain condition, then we need to declare the variable after the
// left expression has been handled but before the right expression is handled
Expand Down Expand Up @@ -594,8 +596,8 @@ impl<'a> Generator<'a> {
buf.writeln("{")?;
self.prepare_ws(def.ws1);

let mut names = Buffer::new(0);
let mut values = Buffer::new(0);
let mut names = Buffer::from_buf_parameters(buf, 0);
let mut values = Buffer::from_buf_parameters(buf, 0);
let mut is_first_variable = true;
if args.len() != def.args.len() {
return Err(CompileError::from(format!(
Expand Down Expand Up @@ -659,7 +661,7 @@ impl<'a> Generator<'a> {
.insert(Cow::Borrowed(arg), LocalMeta::with_ref(var));
}
Expr::Attr(obj, attr) => {
let mut attr_buf = Buffer::new(0);
let mut attr_buf = Buffer::from_buf_parameters(buf, 0);
self.visit_attr(&mut attr_buf, obj, attr)?;

let var = self.locals.resolve(&attr_buf.buf).unwrap_or(attr_buf.buf);
Expand Down Expand Up @@ -748,7 +750,7 @@ impl<'a> Generator<'a> {

self.buf_writable.buf = current_buf;

let mut filter_buf = Buffer::new(buf.indent);
let mut filter_buf = Buffer::from_buf_parameters(buf, buf.indent);
let Filter {
name: filter_name,
arguments,
Expand Down Expand Up @@ -874,7 +876,7 @@ impl<'a> Generator<'a> {
return buf.writeln(";");
};

let mut expr_buf = Buffer::new(0);
let mut expr_buf = Buffer::from_buf_parameters(buf, 0);
self.visit_expr(&mut expr_buf, val)?;

let shadowed = self.is_shadowing_variable(&l.var)?;
Expand Down Expand Up @@ -987,6 +989,9 @@ impl<'a> Generator<'a> {
if block_fragment_write {
self.buf_writable.discard = true;
}
if buf.discard != prev_buf_discard {
self.write_buf_writable(buf)?;
}
buf.discard = prev_buf_discard;

Ok(size_hint)
Expand Down Expand Up @@ -1842,6 +1847,15 @@ impl Buffer {
}
}

fn from_buf_parameters(other: &Buffer, indent: u8) -> Self {
Self {
buf: String::new(),
indent,
start: true,
discard: other.discard,
}
}

fn writeln(&mut self, s: &str) -> Result<(), CompileError> {
if self.discard {
return Ok(());
Expand Down
18 changes: 18 additions & 0 deletions testing/tests/block_fragments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,21 @@ fn test_specific_block() {
let t = RenderInPlace { s1 };
assert_eq!(t.render().unwrap(), "\nSection: [abc]\n");
}

#[derive(Template)]
#[template(
source = r#"{% block empty %}
{% endblock %}

{% if let Some(var) = var %}
{{ var }}
{% endif %}"#,
block = "empty",
ext = "txt"
)]
struct Empty {}

#[test]
fn test_render_only_block() {
assert_eq!(Empty {}.render().unwrap(), "\n");
}