diff --git a/.githooks/pre-commit b/.githooks/pre-commit
new file mode 100755
index 00000000..5e7d1b7a
--- /dev/null
+++ b/.githooks/pre-commit
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+FILES=$(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g')
+[ -z "$FILES" ] && exit 0
+
+echo "> prettier (changed files only)"
+
+# Prettify all selected files
+echo "$FILES" | xargs ./node_modules/.bin/prettier --ignore-unknown --write
+
+echo "> cargo fmt (all files)"
+
+cargo fmt
+
+echo "> taplo fmt (all files)"
+
+taplo fmt
+
+# Add back the modified/prettified files to staging
+echo "$FILES" | xargs git add
+
+exit 0
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 96e47c41..0b864a42 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -200,6 +200,14 @@ jobs:
- run: scripts/install/taplo.sh
- run: taplo fmt --check
+ # Check the formatting of Markdown, TS, JS, JSON, YAML files in the repository
+ prettier:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - run: npm ci
+ - run: npx prettier --check .
+
# Check for typos in the repository based on a static dictionary
typos:
runs-on: ubuntu-latest
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 6322ce38..e9c876f9 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -10,9 +10,9 @@ on:
workflow_dispatch:
env:
- CARGO_TERM_COLOR: always
- RUST_BACKTRACE: 1
- CARGO_INCREMENTAL: 0
+ CARGO_TERM_COLOR: always
+ RUST_BACKTRACE: 1
+ CARGO_INCREMENTAL: 0
jobs:
release-rust-crates:
diff --git a/.gitignore b/.gitignore
index 48323c98..b710162e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,5 @@ terraform.tfstate*
# Terraform variables usually contain sensitive information
terraform.tfvars
terraform.tfvars.json
+
+*dbg*
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000..ad308b42
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,5 @@
+# This file uses terraform's templating syntax rather than YML, so prettier can't parse it
+website/infra/bootstrap/user_data.yml
+
+# Leading whitespace there is intentional as the place for the main issue body
+.github/issue_template.md
diff --git a/Cargo.lock b/Cargo.lock
index ebcf9cc1..3830ef5b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -87,7 +87,7 @@ dependencies = [
[[package]]
name = "bon-cli"
-version = "0.1.0"
+version = "0.2.0"
dependencies = [
"anyhow",
"ra_ap_parser",
@@ -109,6 +109,15 @@ dependencies = [
"syn",
]
+[[package]]
+name = "borsh"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed"
+dependencies = [
+ "cfg_aliases",
+]
+
[[package]]
name = "buildstructor"
version = "0.5.4"
@@ -148,6 +157,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+[[package]]
+name = "cfg_aliases"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
+
[[package]]
name = "ciborium"
version = "0.2.2"
@@ -731,9 +746,9 @@ dependencies = [
[[package]]
name = "ra-ap-rustc_lexer"
-version = "0.63.0"
+version = "0.73.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3bdf98bb457b47b9ae4aeebf867d0ca440c86925e0b6381658c4a02589748c9d"
+checksum = "119bc05b5b6bc3e7f5b67ce8b8080e185da94bd83c447f91b6b3f3ecf60cbab1"
dependencies = [
"unicode-properties",
"unicode-xid",
@@ -741,15 +756,15 @@ dependencies = [
[[package]]
name = "ra_ap_limit"
-version = "0.0.233"
+version = "0.0.241"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f413cec7ebae9832a6f58ba055cb759d682ed0c9a66224ae09b2aa1962d8782"
+checksum = "f9b1b7a869e1a2b68ff8490ff8d3af23b518f83ba41f93192dee0336c0af9b55"
[[package]]
name = "ra_ap_parser"
-version = "0.0.233"
+version = "0.0.241"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54fcf2c5b72af3e20e2fe41582fea9f2147e49bf1dbdfea51193c8e284b7f322"
+checksum = "d2756858e7851f05d6a9119ecb51b10b7ec85414ea06ab6e20e06fd4a0a64599"
dependencies = [
"drop_bomb",
"ra-ap-rustc_lexer",
@@ -759,9 +774,9 @@ dependencies = [
[[package]]
name = "ra_ap_stdx"
-version = "0.0.233"
+version = "0.0.241"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6609b238dea78fc46d847b9f9177b39f92137d7ef73e5e6b062196326705590f"
+checksum = "e743e2c0495f0f1292865d30f7a56349a27f9ceeb61f7b743c96b6ca134e5f76"
dependencies = [
"always-assert",
"crossbeam-channel",
@@ -774,9 +789,9 @@ dependencies = [
[[package]]
name = "ra_ap_syntax"
-version = "0.0.233"
+version = "0.0.241"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4e2abef0d98f554288b767e7b4b0377fde75728142d08f7b17d268c2639f8cb"
+checksum = "9754a818cc20ad5d0acdc2f316082d5ca166ee22db82f5b8d502ba2d5dcc2492"
dependencies = [
"cov-mark",
"either",
@@ -787,7 +802,7 @@ dependencies = [
"ra_ap_stdx",
"ra_ap_text_edit",
"rowan",
- "rustc-hash",
+ "rustc-hash 2.0.0",
"smol_str",
"tracing",
"triomphe",
@@ -795,9 +810,9 @@ dependencies = [
[[package]]
name = "ra_ap_text_edit"
-version = "0.0.233"
+version = "0.0.241"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6be2047bedda5b44c8d8775036cbf8d01dd99c06756524f20991c4249a1bb6ec"
+checksum = "a5f89e975e82f5efe2682bc2c03dda28ad57b0bfd33f64b5831674a25204072b"
dependencies = [
"itertools 0.12.1",
"text-size",
@@ -861,7 +876,7 @@ dependencies = [
"countme",
"hashbrown",
"memoffset",
- "rustc-hash",
+ "rustc-hash 1.1.0",
"text-size",
]
@@ -887,6 +902,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+[[package]]
+name = "rustc-hash"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
+
[[package]]
name = "rustversion"
version = "1.0.17"
@@ -950,10 +971,11 @@ dependencies = [
[[package]]
name = "smol_str"
-version = "0.2.2"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead"
+checksum = "9676b89cd56310a87b93dec47b11af744f34d5fc9f367b829474eec0a891350d"
dependencies = [
+ "borsh",
"serde",
]
diff --git a/README.v3.md b/README.v3.md
index 3071ffb0..2784bc0e 100644
--- a/README.v3.md
+++ b/README.v3.md
@@ -43,7 +43,6 @@
-
# Overview
@@ -182,7 +181,7 @@ Builders generated by `bon`'s macros use the typestate pattern to ensure all req
If something is wrong, a compile error will be created. No matter how you use the generated builder a panic is never possible.
| ⭐ Don't forget to give our repo a [star on Github ⭐](https://github.com/elastio/bon)! |
-| --- |
+| --------------------------------------------------------------------------------------- |
## What's Next?
@@ -209,7 +208,6 @@ If you can't figure something out, consult the docs and maybe use the `🔍 Sear
## Socials
-
diff --git a/benchmarks/compilation/README.md b/benchmarks/compilation/README.md
index 085c455e..d66c1a5a 100644
--- a/benchmarks/compilation/README.md
+++ b/benchmarks/compilation/README.md
@@ -6,7 +6,7 @@ This is a collection of compilation time benchmarks for the code generated by `b
If you'd like to run the benchmarks yourself, first you need to install the following:
-- [`hyperfine`](https://github.com/sharkdp/hyperfine) CLI
+- [`hyperfine`](https://github.com/sharkdp/hyperfine) CLI
If you are on Linux, just run the following commands to install the dependencies:
diff --git a/benchmarks/compilation/results.md b/benchmarks/compilation/results.md
index a9a5ad25..5af1cb01 100644
--- a/benchmarks/compilation/results.md
+++ b/benchmarks/compilation/results.md
@@ -1,12 +1,12 @@
-| Command | Mean [s] | Min [s] | Max [s] | Relative |
-|:---|---:|---:|---:|---:|
-| `structs_100_fields_10 bon` | 2.319 ± 0.021 | 2.278 | 2.350 | 22.80 ± 2.99 |
-| `structs_100_fields_10 bon-overwritable` | 2.240 ± 0.021 | 2.203 | 2.274 | 22.03 ± 2.89 |
-| `structs_100_fields_10 typed-builder` | 1.849 ± 0.011 | 1.838 | 1.878 | 18.18 ± 2.38 |
-| `structs_100_fields_10 derive_builder` | 1.022 ± 0.016 | 0.995 | 1.043 | 10.05 ± 1.32 |
-| `structs_100_fields_10 ` | 0.104 ± 0.012 | 0.088 | 0.124 | 1.02 ± 0.18 |
-| `structs_10_fields_50 bon` | 2.063 ± 0.017 | 2.044 | 2.100 | 20.28 ± 2.66 |
-| `structs_10_fields_50 bon-overwritable` | 2.029 ± 0.029 | 1.998 | 2.102 | 19.95 ± 2.62 |
-| `structs_10_fields_50 typed-builder` | 2.076 ± 0.016 | 2.048 | 2.101 | 20.41 ± 2.67 |
-| `structs_10_fields_50 derive_builder` | 0.432 ± 0.016 | 0.400 | 0.458 | 4.25 ± 0.58 |
-| `structs_10_fields_50 ` | 0.102 ± 0.013 | 0.084 | 0.130 | 1.00 |
+| Command | Mean [s] | Min [s] | Max [s] | Relative |
+| :--------------------------------------- | ------------: | ------: | ------: | -----------: |
+| `structs_100_fields_10 bon` | 2.319 ± 0.021 | 2.278 | 2.350 | 22.80 ± 2.99 |
+| `structs_100_fields_10 bon-overwritable` | 2.240 ± 0.021 | 2.203 | 2.274 | 22.03 ± 2.89 |
+| `structs_100_fields_10 typed-builder` | 1.849 ± 0.011 | 1.838 | 1.878 | 18.18 ± 2.38 |
+| `structs_100_fields_10 derive_builder` | 1.022 ± 0.016 | 0.995 | 1.043 | 10.05 ± 1.32 |
+| `structs_100_fields_10 ` | 0.104 ± 0.012 | 0.088 | 0.124 | 1.02 ± 0.18 |
+| `structs_10_fields_50 bon` | 2.063 ± 0.017 | 2.044 | 2.100 | 20.28 ± 2.66 |
+| `structs_10_fields_50 bon-overwritable` | 2.029 ± 0.029 | 1.998 | 2.102 | 19.95 ± 2.62 |
+| `structs_10_fields_50 typed-builder` | 2.076 ± 0.016 | 2.048 | 2.101 | 20.41 ± 2.67 |
+| `structs_10_fields_50 derive_builder` | 0.432 ± 0.016 | 0.400 | 0.458 | 4.25 ± 0.58 |
+| `structs_10_fields_50 ` | 0.102 ± 0.013 | 0.084 | 0.130 | 1.00 |
diff --git a/benchmarks/runtime/README.md b/benchmarks/runtime/README.md
index 2c26674a..e1637cc0 100644
--- a/benchmarks/runtime/README.md
+++ b/benchmarks/runtime/README.md
@@ -6,8 +6,8 @@ This is a collection of runtime benchmarks for the code generated by `bon` crate
If you'd like to run the benchmarks yourself, first you need to install the following:
-- `Valgrind`. Its `cachegrind` component is used by [`iai`](https://github.com/bheisler/iai) benchmark to display the instruction counts and cache/RAM hits.
-- `cargo-asm`. It's used to get the resulting assembly code for the benchmarked functions.
+- `Valgrind`. Its `cachegrind` component is used by [`iai`](https://github.com/bheisler/iai) benchmark to display the instruction counts and cache/RAM hits.
+- `cargo-asm`. It's used to get the resulting assembly code for the benchmarked functions.
If you are on Ubuntu or Debian, just run the following commands to install the dependencies:
diff --git a/bon-cli/Cargo.toml b/bon-cli/Cargo.toml
index 8b757f33..ebf73851 100644
--- a/bon-cli/Cargo.toml
+++ b/bon-cli/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "bon-cli"
-version = "0.1.0"
+version = "0.2.0"
description = "Dev tool for working with the `bon` crate"
@@ -9,7 +9,7 @@ homepage = "https://bon-rs.com/"
license = "MIT OR Apache-2.0"
repository = "https://github.com/elastio/bon"
-publish = false
+publish = true
[[bin]]
doc = false
@@ -21,6 +21,6 @@ workspace = true
[dependencies]
anyhow = "1.0"
-ra_ap_parser = "=0.0.233"
-ra_ap_syntax = "=0.0.233"
+ra_ap_parser = "=0.0.241"
+ra_ap_syntax = "=0.0.241"
walkdir = "2.5"
diff --git a/bon-macros/src/builder/builder_gen/models.rs b/bon-macros/src/builder/builder_gen/models.rs
index d2d1f82e..c0d5c667 100644
--- a/bon-macros/src/builder/builder_gen/models.rs
+++ b/bon-macros/src/builder/builder_gen/models.rs
@@ -291,7 +291,10 @@ impl BuilderGenCtx {
.map(SpannedKey::into_value)
.unwrap_or_else(|| {
let docs = format!(
- "Tools for manipulating the type state of [`{}`].",
+ "Tools for manipulating the type state of [`{}`].\n\
+ \n\
+ See the [detailed guide](https://bon-rs.com/guide/typestate-api) \
+ that describes how all the pieces here fit together.",
builder_type.ident
);
diff --git a/bon/Cargo.toml b/bon/Cargo.toml
index 71f42c6a..49dcc9cd 100644
--- a/bon/Cargo.toml
+++ b/bon/Cargo.toml
@@ -63,44 +63,8 @@ alloc = []
default = ["std"]
std = ["alloc"]
-# Opts in to the higher MSRV 1.79.0. In this version, Rust stabilized the syntax
-# for bounds in associated type position which can be used to make bounds on generic
-# associated types implied. See the release announcement for more:
-# https://blog.rust-lang.org/2024/06/13/Rust-1.79.0.htmlbounds-in-associated-type-position
-#
-# This feature is useful for the trait `IsComplete` generated by the builder macros.
-# When this feature is enabled, the builder macros use the new syntax for bounds in
-# associated type position, which enables implied `IsSet` bounds for the type state
-# of required members.
-#
-# To understand how this can be used consider the following example:
-#
-# ```rust
-# #[derive(bon::Builder)]
-# struct Example {
-# a: u32,
-# b: Option,
-# }
-#
-# use example_builder::{IsUnset, IsComplete};
-#
-# impl ExampleBuilder {
-# fn build_with_default_b(self) -> Example
-# where
-# State: IsComplete,
-# State::B: IsUnset,
-# {
-# self.b(42).build()
-# }
-# }
-# ```
-#
-# This code wouldn't compile without this feature enabled, because `State: IsComplete`
-# wouldn't automatically imply `State::A: IsSet`, so the builder type state returned
-# after `self.b()` doesn't imply that the member `a` is set, and thus `build()`
-# can't be called.
-#
-# Huge thanks to @harudagondi for suggesting the name of this cargo feature!
+# See the explanation of what this feature does in the docs here:
+# https://bon-rs.com/guide/typestate-api/custom-methods#implied-bounds
implied-bounds = ["bon-macros/implied-bounds"]
# 🔬 Experimental! There may be breaking changes to this feature between *minor* releases,
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..9171c449
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,27 @@
+{
+ "name": "bon",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "devDependencies": {
+ "prettier": "^3.3.3"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
+ "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 00000000..c2436a9f
--- /dev/null
+++ b/package.json
@@ -0,0 +1,5 @@
+{
+ "devDependencies": {
+ "prettier": "^3.3.3"
+ }
+}
diff --git a/scripts/init.sh b/scripts/init.sh
new file mode 100755
index 00000000..6df82a0b
--- /dev/null
+++ b/scripts/init.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+# Script to initialize the repo for development.
+
+set -euxo pipefail
+
+# Install prettier
+npm ci
+
+# Install the pre-commit hook
+ln -s ../../.githooks/pre-commit .git/hooks/pre-commit
diff --git a/website/.vitepress/config.mts b/website/.vitepress/config.mts
index aeaa51c0..487e1bb4 100644
--- a/website/.vitepress/config.mts
+++ b/website/.vitepress/config.mts
@@ -170,7 +170,7 @@ export default defineConfig({
{
text: "Custom Methods",
link: "/guide/typestate-api/custom-methods",
- }
+ },
],
},
{
diff --git a/website/.vitepress/theme/components/PageFooter.vue b/website/.vitepress/theme/components/PageFooter.vue
index 6eb1551a..a912eaf1 100644
--- a/website/.vitepress/theme/components/PageFooter.vue
+++ b/website/.vitepress/theme/components/PageFooter.vue
@@ -1,32 +1,35 @@
-
+