Skip to content

Commit

Permalink
Merge pull request #342 from Kijewski/pr-no-derive
Browse files Browse the repository at this point in the history
Make `derive` optional
  • Loading branch information
GuillaumeGomez authored Feb 9, 2025
2 parents da18bc0 + 98cb423 commit e948374
Show file tree
Hide file tree
Showing 22 changed files with 212 additions and 24 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- run: |
set -eu
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 \
testing testing-alloc testing-no-std testing-renamed
do
Expand Down Expand Up @@ -116,7 +116,7 @@ jobs:
cargo sort --check --check-format --grouped
set -eu
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 \
testing testing-alloc testing-no-std testing-renamed
do
Expand Down Expand Up @@ -159,7 +159,7 @@ jobs:
strategy:
matrix:
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,
testing, testing-alloc, testing-no-std, testing-renamed,
]
Expand Down
1 change: 1 addition & 0 deletions bench-build/.rustfmt.toml
18 changes: 18 additions & 0 deletions bench-build/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions bench-build/LICENSE-APACHE
1 change: 1 addition & 0 deletions bench-build/LICENSE-MIT
55 changes: 55 additions & 0 deletions bench-build/README.md
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions bench-build/_typos.toml
1 change: 1 addition & 0 deletions bench-build/clippy.toml
1 change: 1 addition & 0 deletions bench-build/deny.toml
20 changes: 20 additions & 0 deletions bench-build/run.sh
Original file line number Diff line number Diff line change
@@ -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 changes: 47 additions & 0 deletions bench-build/src/main.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 11 additions & 0 deletions bench-build/templates/greeting.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{%- block hello -%}
Hello
{%- endblock -%}

{%- block hey -%}
Hey
{%- endblock -%}

{%- block hi -%}
Hi
{%- endblock -%}
1 change: 1 addition & 0 deletions bench-build/templates/hello_world.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>{{greeting}}, {{user}}!</h1>
1 change: 1 addition & 0 deletions bench-build/tomlfmt.toml
20 changes: 19 additions & 1 deletion book/src/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Without `default-features = false`, i.e with default features enabled,
the following features are automatically selected for you:

```toml
default = ["config", "std", "urlencode"]
default = ["config", "derive", "std", "urlencode"]
```

This should encompass most features an average user of rinja might need.
Expand All @@ -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**,
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"`

<blockquote class="right" style="padding:0.5ex 1ex; margin:0 0 1ex 1ex; font-size:80%">
Expand Down
28 changes: 15 additions & 13 deletions rinja/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ name = "escape"
harness = false

[dependencies]
rinja_derive = { version = "=0.3.5", path = "../rinja_derive" }

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"
serde = { version = "1.0", optional = true, default-features = false }
serde_json = { version = "1.0", optional = true, default-features = false }
Expand All @@ -43,24 +44,25 @@ criterion = "0.5"
maintenance = { status = "actively-developed" }

[features]
default = ["config", "std", "urlencode"]
full = ["default", "blocks", "code-in-doc", "serde_json"]
default = ["config", "derive", "std", "urlencode", "rinja_derive?/default"]
full = ["default", "blocks", "code-in-doc", "serde_json", "rinja_derive?/full"]

alloc = [
"rinja_derive/alloc",
"rinja_derive?/alloc",
"serde?/alloc",
"serde_json?/alloc",
"percent-encoding?/alloc"
"percent-encoding?/alloc",
]
blocks = ["rinja_derive/blocks"]
code-in-doc = ["rinja_derive/code-in-doc"]
config = ["rinja_derive/config"]
serde_json = ["rinja_derive/serde_json", "dep:serde", "dep:serde_json"]
blocks = ["rinja_derive?/blocks"]
code-in-doc = ["rinja_derive?/code-in-doc"]
config = ["rinja_derive?/config"]
derive = ["rinja_derive"]
serde_json = ["rinja_derive?/serde_json", "dep:serde", "dep:serde_json"]
std = [
"alloc",
"rinja_derive/std",
"rinja_derive?/std",
"serde?/std",
"serde_json?/std",
"percent-encoding?/std"
"percent-encoding?/std",
]
urlencode = ["rinja_derive/urlencode", "dep:percent-encoding"]
urlencode = ["rinja_derive?/urlencode", "dep:percent-encoding"]
5 changes: 3 additions & 2 deletions rinja/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
//! }
//!
//! assert_eq!(
//! Footer { year: 2024, enterprise: "<em>Rinja</em> developers" }.to_string(),
//! "<p>© 2024 &#60;EM&#62;RINJA&#60;/EM&#62; DEVELOPERS</p>",
//! Footer { year: 2025, enterprise: "<em>Rinja</em> developers" }.to_string(),
//! "<p>© 2025 &#60;EM&#62;RINJA&#60;/EM&#62; DEVELOPERS</p>",
//! );
//! // In here you see can Rinja's auto-escaping. You, the developer,
//! // can easily disable the auto-escaping with the `|safe` filter,
Expand Down Expand Up @@ -78,6 +78,7 @@ use core::fmt;
#[cfg(feature = "std")]
use std::io;

#[cfg(feature = "derive")]
pub use rinja_derive::Template;

#[doc(hidden)]
Expand Down
7 changes: 6 additions & 1 deletion rinja_derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,19 @@ prettyplease = "0.2.20"
similar = "2.6.0"
syn = { version = "2.0.3", features = ["full"] }

# must be the same feature list as for rinja
[features]
default = ["config", "derive", "std", "urlencode"]
full = ["default", "blocks", "code-in-doc", "serde_json"]

alloc = []
blocks = ["syn/full"]
code-in-doc = ["dep:pulldown-cmark"]
config = ["dep:basic-toml", "dep:serde", "dep:serde_derive", "parser/config"]
urlencode = []
derive = []
serde_json = []
std = ["alloc"]
urlencode = []

[lints.rust]
# Used in `rinja_derive_standalone` which uses the same source folder, but is not a proc-macro.
Expand Down
5 changes: 4 additions & 1 deletion rinja_derive_standalone/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,14 @@ syn = { version = "2.0.3", features = ["full"] }
default = ["__standalone"]
__standalone = []

alloc = []
blocks = ["syn/full"]
code-in-doc = ["dep:pulldown-cmark"]
config = ["dep:basic-toml", "dep:serde", "dep:serde_derive", "parser/config"]
urlencode = []
derive = []
serde_json = []
std = ["alloc"]
urlencode = []

[lints.rust]
# Used in `rinja_derive` which uses the same source folder, but is a proc-macro.
Expand Down
2 changes: 1 addition & 1 deletion testing-alloc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ rust-version = "1.81"
publish = false

[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"
2 changes: 1 addition & 1 deletion testing-no-std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ rust-version = "1.81"
publish = false

[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"
2 changes: 1 addition & 1 deletion testing-renamed/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ rust-version = "1.81"
publish = false

[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"

0 comments on commit e948374

Please sign in to comment.