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 @@