René Kijewski 3775f4e3a3 Use unicode-ident to determine what is an identifier
Resolves <https://github.com/askama-rs/askama/issues/442>.

The performance is actually slightly better than before. `unicode-ident`
is highly optimized and jump free.

One test from a fuzzer outcome had to be deleted, because it contained
identifiers that weren't actually identifiers. There is still a test
that tests the same problem, but every identifier is simply `x`. In
another fuzzed test a character [`U+E0049`] was removed.

[`U+E0049`]: https://en.wikipedia.org/w/index.php?oldid=1278382889

<details>
<summary>Benchmark results</summary>

```text
$ cd askama_parser && cargo bench

librustdoc/all          time:   [184.47 µs 185.30 µs 186.08 µs]
                        thrpt:  [75.887 MiB/s 76.207 MiB/s 76.548 MiB/s]
                 change:
                        time:   [−1.4364% −0.9672% −0.4738%] (p = 0.00 < 0.05)
                        thrpt:  [+0.4761% +0.9767% +1.4573%]
                        Change within noise threshold.

librustdoc/item_info    time:   [3.3880 µs 3.3892 µs 3.3906 µs]
                        thrpt:  [46.409 MiB/s 46.428 MiB/s 46.445 MiB/s]
                 change:
                        time:   [−3.8735% −3.5927% −3.2949%] (p = 0.00 < 0.05)
                        thrpt:  [+3.4071% +3.7266% +4.0296%]
                        Performance has improved.

librustdoc/item_union   time:   [20.052 µs 20.087 µs 20.126 µs]
                        thrpt:  [49.044 MiB/s 49.140 MiB/s 49.224 MiB/s]
                 change:
                        time:   [−2.2419% −1.8647% −1.5113%] (p = 0.00 < 0.05)
                        thrpt:  [+1.5345% +1.9002% +2.2933%]
                        Performance has improved.

librustdoc/page         time:   [85.828 µs 86.157 µs 86.518 µs]
                        thrpt:  [71.571 MiB/s 71.871 MiB/s 72.147 MiB/s]
                 change:
                        time:   [−1.2728% −0.7668% −0.2512%] (p = 0.00 < 0.05)
                        thrpt:  [+0.2518% +0.7727% +1.2892%]
                        Change within noise threshold.

librustdoc/print_item   time:   [10.065 µs 10.101 µs 10.138 µs]
                        thrpt:  [93.132 MiB/s 93.469 MiB/s 93.806 MiB/s]
                 change:
                        time:   [−3.3793% −2.8352% −2.3267%] (p = 0.00 < 0.05)
                        thrpt:  [+2.3821% +2.9180% +3.4975%]
                        Performance has improved.

librustdoc/short_item_info
                        time:   [9.0741 µs 9.1018 µs 9.1377 µs]
                        thrpt:  [99.148 MiB/s 99.540 MiB/s 99.843 MiB/s]
                 change:
                        time:   [−4.7480% −4.2335% −3.7763%] (p = 0.00 < 0.05)
                        thrpt:  [+3.9245% +4.4207% +4.9847%]
                        Performance has improved.

librustdoc/sidebar      time:   [21.468 µs 21.555 µs 21.648 µs]
                        thrpt:  [57.004 MiB/s 57.252 MiB/s 57.482 MiB/s]
                 change:
                        time:   [−3.7641% −3.0465% −2.4191%] (p = 0.00 < 0.05)
                        thrpt:  [+2.4791% +3.1423% +3.9114%]
                        Performance has improved.

librustdoc/source       time:   [7.9602 µs 7.9780 µs 7.9929 µs]
                        thrpt:  [92.230 MiB/s 92.403 MiB/s 92.609 MiB/s]
                 change:
                        time:   [−1.6386% −1.0684% −0.5875%] (p = 0.00 < 0.05)
                        thrpt:  [+0.5910% +1.0799% +1.6659%]
                        Change within noise threshold.

librustdoc/type_layout_size
                        time:   [4.7821 µs 4.7915 µs 4.8017 µs]
                        thrpt:  [56.406 MiB/s 56.526 MiB/s 56.637 MiB/s]
                 change:
                        time:   [−1.9743% −1.4867% −1.0153%] (p = 0.00 < 0.05)
                        thrpt:  [+1.0257% +1.5091% +2.0141%]
                        Performance has improved.

librustdoc/type_layout  time:   [15.022 µs 15.051 µs 15.076 µs]
                        thrpt:  [178.57 MiB/s 178.88 MiB/s 179.22 MiB/s]
                 change:
                        time:   [−1.5028% −1.0358% −0.5705%] (p = 0.00 < 0.05)
                        thrpt:  [+0.5738% +1.0466% +1.5257%]
                        Change within noise threshold.
```
</details>
2025-05-18 23:04:47 +02:00
2025-04-22 11:34:55 +02:00
2025-05-17 13:20:54 +02:00
2025-05-17 23:21:45 +02:00
2021-02-05 10:47:35 +01:00
2025-03-11 20:18:00 +01:00
2025-04-22 11:34:55 +02:00
2024-11-20 15:00:18 +01:00
2025-03-16 21:58:21 +01:00

askama

Crates.io GitHub Workflow Status Book docs.rs

Askama implements a template rendering engine based on Jinja, and generates type-safe Rust code from your templates at compile time based on a user-defined struct to hold the template's context.

At some point, Askama got forked into Rinja (explained here) before getting merged back into Askama.

All feedback welcome! Feel free to file bugs, requests for documentation and any other feedback to the issue tracker.

You can find the documentation about our syntax, features, configuration in our book: askama.readthedocs.io.

Have a look at our Askama Playground, if you want to try out askama's code generation online.

Feature highlights

  • Construct templates using a familiar, easy-to-use syntax
  • Benefit from the safety provided by Rust's type system
  • Template code is compiled into your crate for optimal performance
  • Debugging features to assist you in template development
  • Templates must be valid UTF-8 and produce UTF-8 when rendered
  • Works on stable Rust

Supported in templates

  • Template inheritance
  • Loops, if/else statements and include support
  • Macro support
  • Variables (no mutability allowed)
  • Some built-in filters, and the ability to use your own
  • Whitespace suppressing with '-' markers
  • Opt-out HTML escaping
  • Syntax customization

How to get started

First, add the askama dependency to your crate's Cargo.toml:

cargo add askama

Now create a directory called templates in your crate root. In it, create a file called hello.html, containing the following:

Hello, {{ name }}!

In any Rust file inside your crate, add the following:

use askama::Template; // bring trait in scope

#[derive(Template)] // this will generate the code...
#[template(path = "hello.html")] // using the template in this path, relative
                                 // to the `templates` dir in the crate root
struct HelloTemplate<'a> { // the name of the struct can be anything
    name: &'a str, // the field name should match the variable name
                   // in your template
}

fn main() {
    let hello = HelloTemplate { name: "world" }; // instantiate your struct
    println!("{}", hello.render().unwrap()); // then render it.
}

You should now be able to compile and run this code.

Description
A template rendering engine based on Jinja, generating type-safe Rust code at compile time.
Readme 5.2 MiB
Languages
Rust 92.9%
HTML 3%
JavaScript 2.9%
Python 0.9%
CSS 0.2%