Crate metadata¶
Facts about the package itself rather than its API. Everything here is
read from Cargo.toml, rust-toolchain.toml, deny.toml and the
justfile at version 0.6.3.
Package identity and how to depend on it¶
| Field | Value |
|---|---|
| Crate name | rtb-tui |
| Library name in Rust code | rtb_tui |
| Version documented here | 0.6.3 |
| Edition | 2021 |
| Minimum supported Rust version | 1.82 |
| License | MIT |
| Repository | https://gitlab.com/phpboyscout/rust/tui |
| Generated API docs | https://docs.rs/rtb-tui |
The crate is pre-1.0, so a minor bump may change the public API. Pin to a minor version rather than a major one if you want a quiet upgrade path.
Cargo features¶
There are none. Cargo.toml declares no [features] table, so:
default-features = falsechanges nothing;- there is no way to compile out the wizard, the render helpers or the spinner independently;
- there is no way to drop
miette,serde_jsonortabledfrom the graph while still using the parts that do not need them.
Taking the crate takes all three components and all eight
dependencies. If that matters for your binary size, depend on
inquire, tabled or console directly instead.
Dependencies¶
Eight runtime dependencies, all pinned to a caret requirement:
| Crate | Requirement | Features | Used for |
|---|---|---|---|
inquire |
0.9.4 | default | The prompts a WizardStep issues; InquireError is re-exported |
tabled |
0.21.0 | derive |
render_table, via Style::psql() |
console |
0.16.4 | default | Term::stderr() and the TTY check in Spinner |
miette |
7.6.0 | fancy |
Diagnostic derive and diagnostic codes on both error enums |
thiserror |
2.0.19 | default | Error derive on both error enums |
async-trait |
0.1.91 | default | WizardStep::prompt is an async fn in a trait |
serde |
1.0.229 | derive |
The Serialize bound on render_json |
serde_json |
1.0.150 | default | to_string_pretty inside render_json |
tokio appears only as a dev-dependency, for the async tests. The
crate does not start or require any particular runtime — Wizard::run
is a plain async fn and you drive it with whatever executor your
binary already has.
miette's fancy feature is the heaviest item in that list: it pulls
in the graphical report renderer and its terminal-handling stack. It is
on unconditionally.
Banned dependencies¶
deny.toml refuses these outright, so a change that reintroduces one
fails the audit job rather than being caught in review:
| Banned crate | Reason |
|---|---|
rust-tool-base |
The crate is extracted from the framework and must never depend back on it |
rtb-cli-bin |
Same rule, for the binary |
anyhow |
thiserror plus miette is the error surface for the whole toolkit |
openssl-sys, native-tls |
No native TLS stack in this graph |
cargo deny also enforces a license allowlist — MIT, MIT-0,
Apache-2.0 (with and without the LLVM exception), BSD-2-Clause,
BSD-3-Clause, ISC, Unicode-DFS-2016, Unicode-3.0, Zlib, CC0-1.0,
MPL-2.0 and 0BSD — and denies yanked crates, wildcard version
requirements, and any source other than crates.io.
One advisory is waived: RUSTSEC-2026-0173 for proc-macro-error2,
reached through tabled_derive. The waiver comment records the
condition for lifting it — tabled dropping proc-macro-error2, or
this crate moving to a different table library.
Lint policy¶
| Setting | Level | Where |
|---|---|---|
unsafe_code |
deny at the package level, forbid in src/lib.rs |
Cargo.toml, src/lib.rs |
missing_docs |
warn |
Cargo.toml |
clippy::pedantic, clippy::nursery, clippy::cargo |
warn |
Cargo.toml |
unsafe_code is deny rather than forbid at the package level
specifically so an individual test file can #![allow(...)] when it
genuinely needs to; the library itself carries
#![forbid(unsafe_code)], and that is the guarantee that ships.
Four clippy lints are switched off: module_name_repetitions,
missing_errors_doc, missing_panics_doc and
multiple_crate_versions.
CI runs cargo clippy --all-targets -- -D warnings, so every one of
those warn levels is an error in the pipeline.
Toolchain and MSRV¶
rust-toolchain.toml pins an exact stable release — 1.97.1 — with
rustfmt, clippy and rust-src. The pin is exact rather than the
floating stable channel so that a new stable release cannot change
compiler output underneath CI without a reviewable commit.
Note that this is not the MSRV. Cargo.toml declares
rust-version = "1.82", but the pinned toolchain and therefore every
CI job builds on 1.97.1. Nothing in this repository compiles the crate
on 1.82, so the declared MSRV is a statement of intent rather than a
tested guarantee. Treat "works on 1.82" as unverified until you have
built it yourself on that toolchain.
Running the checks locally¶
just targets, from the justfile:
| Target | Command it runs |
|---|---|
just check (default) |
cargo check --all-targets |
just build |
cargo build --all-targets |
just fmt / just fmt-check |
cargo fmt --all / --check |
just lint |
cargo clippy --all-targets -- -D warnings |
just test |
cargo nextest run, falling back to cargo test |
just audit |
cargo deny check |
just docs |
cargo doc --no-deps with RUSTDOCFLAGS="-D warnings" |
just site-build / just site-serve |
zensical build --clean / zensical serve |
just ci |
fmt-check, lint, docs, test, audit in that order |
just ci is the local mirror of the merge-request gate. The docs site
build is not part of it: the site is built and deployed from main by
a separate pipeline job, so a docs change is not gated on the site
compiling. Run just site-build yourself before raising a docs merge
request.
All tests run headless. None of them need a TTY, and none of them talk to the network.
Releases¶
Releases are cut by release-plz from
Conventional Commits. Pushing to main opens or updates a release
merge request; merging that MR creates the tag and the release. Tags
are named rtb-tui-v<version> even though this is a single-crate
repository, for consistency with the other phpboyscout/rust repos and
with the tags the monorepo already carries.
Do not tag manually, and do not run cargo update as part of a
release — release-plz is configured with dependencies_update =
false so that dependency churn goes through CI as its own change.
Known documentation defects¶
The generated rustdoc on docs.rs contains claims that the code does not support. They are listed here so a reader who hits one knows which source to believe. In every case below, the code is right and the comment is wrong.
| Where | The claim | What the code does |
|---|---|---|
Spinner::finish |
"Idempotent — safe to call multiple times" | finish takes self by value, so a second call does not compile. The cleanup is idempotent; the method cannot be called twice |
render_json |
Typical failure causes are "non-string Map keys or non-finite floats" |
f64::NAN and f64::INFINITY serialise to null without error, and integer map keys are stringified without error. Only a key that is not string-like at all — a tuple, say — actually fails |
WizardBuilder::build |
Construction "is typestate-checked at the type level in v0.2 (bon-derived); for v0.1 the panic-on-misuse contract is documented and enforced via a test" |
At 0.6.3 the builder still panics, is not bon-derived, and no test in tests/ calls build() without initial() |
Wizard |
"Construction is typestate-style via Wizard::builder" |
The builder is a plain accumulator with Option fields; nothing is checked at the type level |
src/lib.rs, src/render.rs, src/spinner.rs |
Point at docs/development/specs/2026-05-06-rtb-tui-v0.1.md, "W2 in the spec", "W3 in the spec" as the authoritative contract |
No such file exists in this repository. The reasoning those references stand in for is written out in Explanation |
rust-toolchain.toml |
The exact pin is needed because "trybuild compile-fail .stderr fixtures match rustc's diagnostic output byte-for-byte" |
This crate has no trybuild dependency, no tests/ui directory and no .stderr fixtures. The rationale was carried over from the monorepo |