Skip to content

Implement compound assignments (e.g. {% mut a += 1 %})#685

Merged
GuillaumeGomez merged 2 commits intoaskama-rs:mainfrom
Kijewski:pr-compound-assignment
Jan 30, 2026
Merged

Implement compound assignments (e.g. {% mut a += 1 %})#685
GuillaumeGomez merged 2 commits intoaskama-rs:mainfrom
Kijewski:pr-compound-assignment

Conversation

@Kijewski
Copy link
Copy Markdown
Member

@Kijewski Kijewski commented Jan 28, 2026

I think it can be quite useful to modify variables that are declared inside a template.

Is it possible to "resolve" a discussion? Let's find out!

Resolves #662.

The answer is: no.

@Kijewski Kijewski force-pushed the pr-compound-assignment branch from 1986b21 to 6be1999 Compare January 28, 2026 17:53
@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

Huuuuuuum. I don't like the fact that we overload the let operator for that. Since it's not standard, why not add a new keyword instead? Like mutate or modify or update?

@Kijewski
Copy link
Copy Markdown
Member Author

{% mut a += b %}?

@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

Agreed!

@Kijewski Kijewski force-pushed the pr-compound-assignment branch from 6be1999 to 4b0ee18 Compare January 28, 2026 23:03
@Kijewski Kijewski changed the title Implement compound assignments (e.g. {% let a += 1 %}) Implement compound assignments (e.g. {% mut a += 1 %}) Jan 28, 2026
Comment thread askama_parser/src/node.rs
@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

Note for me of tomorrow for review: check how operators are checked, if an operator is needed, check it's only one of the following: =, +=, -=, /=, *=, ^=, %=, &=, ~=. Also check for error messages.

@Kijewski
Copy link
Copy Markdown
Member Author

Kijewski commented Jan 29, 2026

~=? Should be |= I guess? :)

@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

I was sure the ~ was an operator in rust. But I forgot |= for sure. 😆

Comment thread askama_parser/src/lib.rs

fn filter<'a: 'l, 'l>(i: &mut InputStream<'a, 'l>) -> ParseResult<'a, Filter<'a>> {
preceded(('|', not('|')), cut_err(Filter::parse)).parse_next(i)
preceded(('|', not(one_of(['|', '=']))), cut_err(Filter::parse)).parse_next(i)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oof, nice catch.

Comment thread book/src/template_syntax.md Outdated
```jinja
{% let mut counter = 0 %}
{% for i in 1..=10 %}
{% mut counter += 1 %}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To ensure the output is as described.

Suggested change
{% mut counter += 1 %}
{%- mut counter += 1 -%}

Copy link
Copy Markdown
Member Author

@Kijewski Kijewski Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was not the quite problem with the code (I ignored spaces). I wrote += 1, but I meant += i. :) Fixed.

Comment thread askama_parser/src/lib.rs

fn filter<'a: 'l, 'l>(i: &mut InputStream<'a, 'l>) -> ParseResult<'a, Filter<'a>> {
preceded(('|', not('|')), cut_err(Filter::parse)).parse_next(i)
preceded(('|', not(one_of(['|', '=']))), cut_err(Filter::parse)).parse_next(i)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a ui test for this one please?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Comment thread askama_parser/src/expr.rs
Ok("&")
} else {
let good = keyword("bitand").value(None);
let bad = ('&', not(one_of(['&', '=']))).span().map(Some);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a ui test for this one.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already tested by testing/tests/ui/iso646.rs.

@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

Looks good to me, thanks! Please add the ui tests I mentioned, then it should be ready for merge. Well done!

@Kijewski Kijewski force-pushed the pr-compound-assignment branch 2 times, most recently from a7827b0 to 47366c1 Compare January 30, 2026 02:28
@Kijewski Kijewski force-pushed the pr-compound-assignment branch from 47366c1 to 579f928 Compare January 30, 2026 02:39
@GuillaumeGomez
Copy link
Copy Markdown
Collaborator

Thanks!

@GuillaumeGomez GuillaumeGomez merged commit f06df54 into askama-rs:main Jan 30, 2026
50 checks passed
Comment thread askama_parser/src/node.rs
// is valid rust code, because the value of any assignment (compound or not) is `()`.
// This way the generator does not need to know about compound assignments for them
// to work.
Ok(Box::new(Node::Let(WithSpan::new(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Late thought about this: why not creating a new type for it? Would allow to generate a cleaner AST too.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, laziness on my side. Nothing more, nothing less. :)

@Kijewski Kijewski deleted the pr-compound-assignment branch February 9, 2026 22:09
@GuillaumeGomez GuillaumeGomez mentioned this pull request Apr 5, 2026
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants