Skip to content

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
[dependencies]
rtb-tui = "0.6"

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 = false changes 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_json or tabled from 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