mirror of
https://github.com/askama-rs/askama.git
synced 2025-09-30 22:41:13 +00:00
Merge pull request #342 from Kijewski/pr-no-derive
Make `derive` optional
This commit is contained in:
commit
e9483747d1
6
.github/workflows/rust.yml
vendored
6
.github/workflows/rust.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
|||||||
- run: |
|
- run: |
|
||||||
set -eu
|
set -eu
|
||||||
for PKG in \
|
for PKG in \
|
||||||
examples/actix-web-app examples/axum-app examples/poem-app examples/rocket-app examples/salvo-app examples/warp-app fuzzing \
|
bench-build examples/actix-web-app examples/axum-app examples/poem-app examples/rocket-app examples/salvo-app examples/warp-app fuzzing \
|
||||||
rinja rinja_derive rinja_derive_standalone rinja_parser \
|
rinja rinja_derive rinja_derive_standalone rinja_parser \
|
||||||
testing testing-alloc testing-no-std testing-renamed
|
testing testing-alloc testing-no-std testing-renamed
|
||||||
do
|
do
|
||||||
@ -116,7 +116,7 @@ jobs:
|
|||||||
cargo sort --check --check-format --grouped
|
cargo sort --check --check-format --grouped
|
||||||
set -eu
|
set -eu
|
||||||
for PKG in \
|
for PKG in \
|
||||||
examples/actix-web-app examples/axum-app examples/poem-app examples/rocket-app examples/salvo-app examples/warp-app fuzzing \
|
bench-build examples/actix-web-app examples/axum-app examples/poem-app examples/rocket-app examples/salvo-app examples/warp-app fuzzing \
|
||||||
rinja rinja_derive rinja_derive_standalone rinja_parser \
|
rinja rinja_derive rinja_derive_standalone rinja_parser \
|
||||||
testing testing-alloc testing-no-std testing-renamed
|
testing testing-alloc testing-no-std testing-renamed
|
||||||
do
|
do
|
||||||
@ -159,7 +159,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
package: [
|
package: [
|
||||||
examples/actix-web-app, examples/axum-app, examples/poem-app, examples/rocket-app, examples/salvo-app, examples/warp-app, fuzzing,
|
bench-build, examples/actix-web-app, examples/axum-app, examples/poem-app, examples/rocket-app, examples/salvo-app, examples/warp-app, fuzzing,
|
||||||
rinja, rinja_derive, rinja_derive_standalone, rinja_parser,
|
rinja, rinja_derive, rinja_derive_standalone, rinja_parser,
|
||||||
testing, testing-alloc, testing-no-std, testing-renamed,
|
testing, testing-alloc, testing-no-std, testing-renamed,
|
||||||
]
|
]
|
||||||
|
1
bench-build/.rustfmt.toml
Symbolic link
1
bench-build/.rustfmt.toml
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../.rustfmt.toml
|
18
bench-build/Cargo.toml
Normal file
18
bench-build/Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
[package]
|
||||||
|
name = "bench-build"
|
||||||
|
version = "0.3.5"
|
||||||
|
authors = ["rinja-rs developers"]
|
||||||
|
edition = "2021"
|
||||||
|
rust-version = "1.81"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rinja = { path = "../rinja", version = "0.3.5", default-features = false, features = ["std"] }
|
||||||
|
rinja_derive = { path = "../rinja_derive", version = "0.3.5", features = ["std"] }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
derive = ["rinja/derive"]
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
members = ["."]
|
1
bench-build/LICENSE-APACHE
Symbolic link
1
bench-build/LICENSE-APACHE
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../LICENSE-APACHE
|
1
bench-build/LICENSE-MIT
Symbolic link
1
bench-build/LICENSE-MIT
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../LICENSE-MIT
|
55
bench-build/README.md
Normal file
55
bench-build/README.md
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
Run the script `./run.sh` in this directory to compare the compile compile of `rinja`
|
||||||
|
|
||||||
|
* uses feature `derive` vs
|
||||||
|
* it does not use that feature.
|
||||||
|
|
||||||
|
The output might look like:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Benchmark 1: cargo run --features=derive
|
||||||
|
Time (mean ± σ): 3.378 s ± 0.041 s [User: 7.944 s, System: 1.018 s]
|
||||||
|
Range (min … max): 3.345 s … 3.424 s 3 runs
|
||||||
|
|
||||||
|
Benchmark 2: cargo run
|
||||||
|
Time (mean ± σ): 3.283 s ± 0.130 s [User: 8.400 s, System: 1.091 s]
|
||||||
|
Range (min … max): 3.141 s … 3.398 s 3 runs
|
||||||
|
|
||||||
|
Summary
|
||||||
|
cargo run ran
|
||||||
|
1.03 ± 0.04 times faster than cargo run --features=derive
|
||||||
|
|
||||||
|
----------
|
||||||
|
|
||||||
|
Benchmark 1: cargo run --release --features=derive
|
||||||
|
Time (mean ± σ): 4.733 s ± 0.050 s [User: 9.026 s, System: 0.749 s]
|
||||||
|
Range (min … max): 4.689 s … 4.788 s 3 runs
|
||||||
|
|
||||||
|
Benchmark 2: cargo run --release
|
||||||
|
Time (mean ± σ): 4.504 s ± 0.032 s [User: 9.010 s, System: 0.733 s]
|
||||||
|
Range (min … max): 4.481 s … 4.541 s 3 runs
|
||||||
|
|
||||||
|
Summary
|
||||||
|
cargo run --release ran
|
||||||
|
1.05 ± 0.01 times faster than cargo run --release --features=derive
|
||||||
|
```
|
||||||
|
|
||||||
|
This shows that – while it is less convenient – for small projects it might be better
|
||||||
|
to use the following setup.
|
||||||
|
This might be especially true if you are using `rinja` in a library.
|
||||||
|
Without the feature, `cargo` will be able to compile more dependencies in parallel.
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# Cargo.toml
|
||||||
|
[dependencies]
|
||||||
|
rinja = { version = "0.3.5", default-features = false, features = ["std"] }
|
||||||
|
rinja_derive = { version = "0.3.5", features = ["std"] }
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// lib.rs
|
||||||
|
use rinja::Template as _;
|
||||||
|
use rinja_derive::Template;
|
||||||
|
```
|
||||||
|
|
||||||
|
The script uses [hyperfine](https://crates.io/crates/hyperfine).
|
||||||
|
Install it with `cargo install hyperfine`.
|
1
bench-build/_typos.toml
Symbolic link
1
bench-build/_typos.toml
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../_typos.toml
|
1
bench-build/clippy.toml
Symbolic link
1
bench-build/clippy.toml
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../clippy.toml
|
1
bench-build/deny.toml
Symbolic link
1
bench-build/deny.toml
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../deny.toml
|
20
bench-build/run.sh
Executable file
20
bench-build/run.sh
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
cd "$(dirname "${BASH_SOURCE[0]}")"
|
||||||
|
|
||||||
|
mkdir -p target
|
||||||
|
hyperfine \
|
||||||
|
--runs=3 \
|
||||||
|
--warmup=1 \
|
||||||
|
--prepare='rm -r target' \
|
||||||
|
'cargo run --features=derive' \
|
||||||
|
'cargo run'
|
||||||
|
echo
|
||||||
|
echo ----------
|
||||||
|
echo
|
||||||
|
hyperfine \
|
||||||
|
--runs=3 \
|
||||||
|
--warmup=1 \
|
||||||
|
--prepare='rm -r target' \
|
||||||
|
'cargo run --release --features=derive' \
|
||||||
|
'cargo run --release'
|
47
bench-build/src/main.rs
Normal file
47
bench-build/src/main.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use rinja::Template as _;
|
||||||
|
use rinja_derive::Template;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut args = std::env::args().fuse().skip(1);
|
||||||
|
let greeting = args.next();
|
||||||
|
let user = args.next();
|
||||||
|
|
||||||
|
let tmpl = HelloWorld {
|
||||||
|
greeting: greeting.as_deref().unwrap_or("hi").parse().unwrap(),
|
||||||
|
user: user.as_deref().unwrap_or("user"),
|
||||||
|
};
|
||||||
|
println!("{}", tmpl.render().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Template)]
|
||||||
|
#[template(path = "hello_world.html")]
|
||||||
|
struct HelloWorld<'a> {
|
||||||
|
greeting: Greeting,
|
||||||
|
user: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Template)]
|
||||||
|
#[template(path = "greeting.html")]
|
||||||
|
enum Greeting {
|
||||||
|
#[template(block = "hello")]
|
||||||
|
Hello,
|
||||||
|
#[template(block = "hey")]
|
||||||
|
Hey,
|
||||||
|
#[template(block = "hi")]
|
||||||
|
Hi,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Greeting {
|
||||||
|
type Err = &'static str;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
match s {
|
||||||
|
"hello" => Ok(Self::Hello),
|
||||||
|
"hey" => Ok(Self::Hey),
|
||||||
|
"hi" => Ok(Self::Hi),
|
||||||
|
_ => Err("Valid greetings: <hello | hey | hi>"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
bench-build/templates/greeting.html
Normal file
11
bench-build/templates/greeting.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{%- block hello -%}
|
||||||
|
Hello
|
||||||
|
{%- endblock -%}
|
||||||
|
|
||||||
|
{%- block hey -%}
|
||||||
|
Hey
|
||||||
|
{%- endblock -%}
|
||||||
|
|
||||||
|
{%- block hi -%}
|
||||||
|
Hi
|
||||||
|
{%- endblock -%}
|
1
bench-build/templates/hello_world.html
Normal file
1
bench-build/templates/hello_world.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<h1>{{greeting}}, {{user}}!</h1>
|
1
bench-build/tomlfmt.toml
Symbolic link
1
bench-build/tomlfmt.toml
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../tomlfmt.toml
|
@ -35,7 +35,7 @@ Without `default-features = false`, i.e with default features enabled,
|
|||||||
the following features are automatically selected for you:
|
the following features are automatically selected for you:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
default = ["config", "std", "urlencode"]
|
default = ["config", "derive", "std", "urlencode"]
|
||||||
```
|
```
|
||||||
|
|
||||||
This should encompass most features an average user of rinja might need.
|
This should encompass most features an average user of rinja might need.
|
||||||
@ -44,6 +44,24 @@ This should encompass most features an average user of rinja might need.
|
|||||||
and if you want it to be usable in by other users and in **other projects**,
|
and if you want it to be usable in by other users and in **other projects**,
|
||||||
then you should probably **opt-out of features you do not need**.*
|
then you should probably **opt-out of features you do not need**.*
|
||||||
|
|
||||||
|
### `"derive"`
|
||||||
|
|
||||||
|
<blockquote class="right" style="padding:0.5ex 1ex; margin:0 0 1ex 1ex; font-size:80%">
|
||||||
|
enabled by <code>"default"</code>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
This feature enables `#[derive(Template)]`. Without it the trait `rinja::Template` will still be
|
||||||
|
available, but if you want to derive a template, you have to manually depend on `rinja_derive`.
|
||||||
|
`rinja_derive` should be used with the same features as `rinja`.
|
||||||
|
|
||||||
|
Not using this feature might be useful e.g. if you are writing a library with manual filters
|
||||||
|
for rinja, without any templates. It might also very slightly speed-up the compilation,
|
||||||
|
because more dependencies can be compiled in parallel, because `rinja` won't transitively depend
|
||||||
|
on e.g. `syn` or `proc-macro2`. On the author's PC the compilation of a trivial hello-world example
|
||||||
|
was about 0.2s faster without the feature when compiled in release mode.
|
||||||
|
|
||||||
|
*If you are writing a library that uses rinja, consider **not using** this default-feature.*
|
||||||
|
|
||||||
### `"config"`
|
### `"config"`
|
||||||
|
|
||||||
<blockquote class="right" style="padding:0.5ex 1ex; margin:0 0 1ex 1ex; font-size:80%">
|
<blockquote class="right" style="padding:0.5ex 1ex; margin:0 0 1ex 1ex; font-size:80%">
|
||||||
|
@ -24,10 +24,11 @@ name = "escape"
|
|||||||
harness = false
|
harness = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rinja_derive = { version = "=0.3.5", path = "../rinja_derive" }
|
|
||||||
|
|
||||||
itoa = "1.0.11"
|
itoa = "1.0.11"
|
||||||
|
|
||||||
|
# needed by feature "derive"
|
||||||
|
rinja_derive = { version = "=0.3.5", path = "../rinja_derive", default-features = false, optional = true }
|
||||||
|
|
||||||
# needed by feature "serde_json"
|
# needed by feature "serde_json"
|
||||||
serde = { version = "1.0", optional = true, default-features = false }
|
serde = { version = "1.0", optional = true, default-features = false }
|
||||||
serde_json = { version = "1.0", optional = true, default-features = false }
|
serde_json = { version = "1.0", optional = true, default-features = false }
|
||||||
@ -43,24 +44,25 @@ criterion = "0.5"
|
|||||||
maintenance = { status = "actively-developed" }
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["config", "std", "urlencode"]
|
default = ["config", "derive", "std", "urlencode", "rinja_derive?/default"]
|
||||||
full = ["default", "blocks", "code-in-doc", "serde_json"]
|
full = ["default", "blocks", "code-in-doc", "serde_json", "rinja_derive?/full"]
|
||||||
|
|
||||||
alloc = [
|
alloc = [
|
||||||
"rinja_derive/alloc",
|
"rinja_derive?/alloc",
|
||||||
"serde?/alloc",
|
"serde?/alloc",
|
||||||
"serde_json?/alloc",
|
"serde_json?/alloc",
|
||||||
"percent-encoding?/alloc"
|
"percent-encoding?/alloc",
|
||||||
]
|
]
|
||||||
blocks = ["rinja_derive/blocks"]
|
blocks = ["rinja_derive?/blocks"]
|
||||||
code-in-doc = ["rinja_derive/code-in-doc"]
|
code-in-doc = ["rinja_derive?/code-in-doc"]
|
||||||
config = ["rinja_derive/config"]
|
config = ["rinja_derive?/config"]
|
||||||
serde_json = ["rinja_derive/serde_json", "dep:serde", "dep:serde_json"]
|
derive = ["rinja_derive"]
|
||||||
|
serde_json = ["rinja_derive?/serde_json", "dep:serde", "dep:serde_json"]
|
||||||
std = [
|
std = [
|
||||||
"alloc",
|
"alloc",
|
||||||
"rinja_derive/std",
|
"rinja_derive?/std",
|
||||||
"serde?/std",
|
"serde?/std",
|
||||||
"serde_json?/std",
|
"serde_json?/std",
|
||||||
"percent-encoding?/std"
|
"percent-encoding?/std",
|
||||||
]
|
]
|
||||||
urlencode = ["rinja_derive/urlencode", "dep:percent-encoding"]
|
urlencode = ["rinja_derive?/urlencode", "dep:percent-encoding"]
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! assert_eq!(
|
//! assert_eq!(
|
||||||
//! Footer { year: 2024, enterprise: "<em>Rinja</em> developers" }.to_string(),
|
//! Footer { year: 2025, enterprise: "<em>Rinja</em> developers" }.to_string(),
|
||||||
//! "<p>© 2024 <EM>RINJA</EM> DEVELOPERS</p>",
|
//! "<p>© 2025 <EM>RINJA</EM> DEVELOPERS</p>",
|
||||||
//! );
|
//! );
|
||||||
//! // In here you see can Rinja's auto-escaping. You, the developer,
|
//! // In here you see can Rinja's auto-escaping. You, the developer,
|
||||||
//! // can easily disable the auto-escaping with the `|safe` filter,
|
//! // can easily disable the auto-escaping with the `|safe` filter,
|
||||||
@ -78,6 +78,7 @@ use core::fmt;
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
#[cfg(feature = "derive")]
|
||||||
pub use rinja_derive::Template;
|
pub use rinja_derive::Template;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -38,14 +38,19 @@ prettyplease = "0.2.20"
|
|||||||
similar = "2.6.0"
|
similar = "2.6.0"
|
||||||
syn = { version = "2.0.3", features = ["full"] }
|
syn = { version = "2.0.3", features = ["full"] }
|
||||||
|
|
||||||
|
# must be the same feature list as for rinja
|
||||||
[features]
|
[features]
|
||||||
|
default = ["config", "derive", "std", "urlencode"]
|
||||||
|
full = ["default", "blocks", "code-in-doc", "serde_json"]
|
||||||
|
|
||||||
alloc = []
|
alloc = []
|
||||||
blocks = ["syn/full"]
|
blocks = ["syn/full"]
|
||||||
code-in-doc = ["dep:pulldown-cmark"]
|
code-in-doc = ["dep:pulldown-cmark"]
|
||||||
config = ["dep:basic-toml", "dep:serde", "dep:serde_derive", "parser/config"]
|
config = ["dep:basic-toml", "dep:serde", "dep:serde_derive", "parser/config"]
|
||||||
urlencode = []
|
derive = []
|
||||||
serde_json = []
|
serde_json = []
|
||||||
std = ["alloc"]
|
std = ["alloc"]
|
||||||
|
urlencode = []
|
||||||
|
|
||||||
[lints.rust]
|
[lints.rust]
|
||||||
# Used in `rinja_derive_standalone` which uses the same source folder, but is not a proc-macro.
|
# Used in `rinja_derive_standalone` which uses the same source folder, but is not a proc-macro.
|
||||||
|
@ -47,11 +47,14 @@ syn = { version = "2.0.3", features = ["full"] }
|
|||||||
default = ["__standalone"]
|
default = ["__standalone"]
|
||||||
__standalone = []
|
__standalone = []
|
||||||
|
|
||||||
|
alloc = []
|
||||||
blocks = ["syn/full"]
|
blocks = ["syn/full"]
|
||||||
code-in-doc = ["dep:pulldown-cmark"]
|
code-in-doc = ["dep:pulldown-cmark"]
|
||||||
config = ["dep:basic-toml", "dep:serde", "dep:serde_derive", "parser/config"]
|
config = ["dep:basic-toml", "dep:serde", "dep:serde_derive", "parser/config"]
|
||||||
urlencode = []
|
derive = []
|
||||||
serde_json = []
|
serde_json = []
|
||||||
|
std = ["alloc"]
|
||||||
|
urlencode = []
|
||||||
|
|
||||||
[lints.rust]
|
[lints.rust]
|
||||||
# Used in `rinja_derive` which uses the same source folder, but is a proc-macro.
|
# Used in `rinja_derive` which uses the same source folder, but is a proc-macro.
|
||||||
|
@ -7,6 +7,6 @@ rust-version = "1.81"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rinja = { path = "../rinja", version = "0.3.5", default-features = false, features = ["alloc"] }
|
rinja = { path = "../rinja", version = "0.3.5", default-features = false, features = ["alloc", "derive"] }
|
||||||
|
|
||||||
assert_matches = "1.5.0"
|
assert_matches = "1.5.0"
|
||||||
|
@ -7,6 +7,6 @@ rust-version = "1.81"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rinja = { path = "../rinja", version = "0.3.5", default-features = false }
|
rinja = { path = "../rinja", version = "0.3.5", default-features = false, features = ["derive"] }
|
||||||
|
|
||||||
assert_matches = "1.5.0"
|
assert_matches = "1.5.0"
|
||||||
|
@ -7,6 +7,6 @@ rust-version = "1.81"
|
|||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
some_name = { package = "rinja", path = "../rinja", version = "0.3.5", default-features = false }
|
some_name = { package = "rinja", path = "../rinja", version = "0.3.5", default-features = false, features = ["derive"] }
|
||||||
|
|
||||||
assert_matches = "1.5.0"
|
assert_matches = "1.5.0"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user