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

Feature request: enhance match to include multiple targets #904

Closed
martinellison opened this issue Nov 11, 2023 · 1 comment · Fixed by #911
Closed

Feature request: enhance match to include multiple targets #904

martinellison opened this issue Nov 11, 2023 · 1 comment · Fixed by #911

Comments

@martinellison
Copy link

martinellison commented Nov 11, 2023

This has previously been discussed at #711 (comment) but I would like to move it to its own issue as it can be implemented separately.

The request is to enhance Askana's syntax for the match block (see https://djc.github.io/askama/template_syntax.html#match) to handle multiple targets in the same 'arm'.

See https://doc.rust-lang.org/reference/expressions/match-expr.html for the Rust syntax in the Reference Manual. Note that a match arm can have multiple targets; the object of this feature request is to replicate this in Askama. (I am not requesting 'match arm guards' (if clauses)).

So given code like

enum Suit {Clubs, Diamonds, Hearts, Spades}

one could write a template like

The card is
{% match suit %}
   {% when Suit::Clubs or Suit::Spades %}
     black
   {% when Suit::Diamonds or Suit::Hearts %}
     red
{% endmatch %}

Alternatively, or could be replaced by | in the proposed design, but I think Askama prefers keywords to symbols.

Looking at the code, combinator/mod.rs(587)ff defines how match statements are stored in the parse structure and how the code is parsed into this structure, and line 232ff covers when arms. So the target field would need to be a vector of Targets, and the when() function would need to be able to parse the modified when syntax., and the parse() function for Match around 595 also would need changing.

The Match structure is used in generator.rs around 544ff to generate the Rust code. This currently calls visit_target at 1559ff to generate the actual target; this would need to be changed around 576 to a call for each target and to output intervening | tokens.

There is some code around heritage.rs(93). I'm not sure what it does, but it looks like it moves the match arms without change, so maybe it does not require any change.

Also, the documentation will need changing, of course. near template_syntax.md(417)ff.

The test could look something like the following (in testing/tests/matches.rs), with the template above in testing/templates/match-enum.html).

enum Suit {Clubs, Diamonds, Hearts, Spades}
#[derive(Template)]
#[template(path = "match-enum.html")]
struct MatchEnumTemplate {
    item: Suit,
}

#[test]
fn test_match_enum() {
    let s = MatchEnumTemplate { item: Suit::Clubs};
    assert_eq!(s.render().unwrap(), "\nThe card is black\n");

    let s = MatchEnumTemplate { item: Suit::Hearts};
    assert_eq!(s.render().unwrap(), "\nThe card is red\n");

}
@djc
Copy link
Owner

djc commented Nov 16, 2023

I'm happy to review a PR for this as proposed.

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 a pull request may close this issue.

2 participants