Contributing
September 20, 2026 ยท View on GitHub
Thanks for taking the time. This is a small, opinionated crate, so a short read now saves a long review later.
Getting set up
git clone https://github.com/noahbclarkson/typesafe-api-rs
cd typesafe-api-rs
cargo test --workspace --all-features
You need a stable toolchain with rustfmt and clippy. The MSRV is 1.88 and CI
enforces it, so avoid APIs newer than that.
Tests that hit the live API are #[ignore]d and read TYPESAFE_API_KEY. They
are never part of CI on pull requests. To run them:
TYPESAFE_API_KEY=... cargo test --workspace --all-features -- --ignored
Before you open a pull request
cargo fmt --all
cargo clippy --workspace --all-targets --all-features
cargo test --workspace --all-features
cargo doc --workspace --all-features --no-deps
CI runs these plus a feature powerset check, minimal dependency versions,
cargo-deny, cargo-semver-checks, and a spell check.
What good looks like here
Read docs/DESIGN.md first if the change touches the
public API. It records why things are the way they are, and a pull request that
contradicts it should say so and argue the case.
The wire format is the contract. Anything that changes the JSON sent or
accepted needs a test in crates/typesafe-api/tests/wire.rs, ideally quoting the
payload from the API reference.
Errors are for the person reading them at 2am. An error should say what was being done, what went wrong, and whether trying again could help. Prefer a struct variant with named fields over a formatted string.
Do not hide the wire. Every convenience must be built from a public,
inspectable lower layer. If a caller cannot get at the Request that a helper
builds, the helper is wrong.
Comments explain why, not what. The code says what it does. A comment earns its place by recording a decision, a constraint, or a surprise. Doc comments on public items are required; running commentary inside functions is not wanted.
New dependencies need a reason. Say in the pull request what it replaces, what it costs in compile time, and why the standard library or an existing dependency will not do. Anything reachable from the default feature set is held to a higher bar than something behind a feature flag.
Commits
Commit messages follow Conventional Commits:
feat(client): honour Retry-After on 429 responses
fix(answer): keep unknown answer kinds instead of dropping them
docs(readme): show the derive layer before the raw one
The changelog and version bumps are generated from these by release-plz, so a
feat: or a ! breaking marker has real consequences. Squash-merge is the
default; the pull request title becomes the commit.
Releasing
Maintainers only. release-plz opens a release pull request with the version
bump and changelog; merging it publishes to crates.io.
Code of conduct
By participating you agree to the Code of Conduct.