What rtb-tui does not do¶
Everything on this page is a deliberate absence or a known gap at version 0.6.3, not a defect to report. If you are about to work around one of these, the workaround is the right move.
It is not a full-screen terminal UI¶
Despite the name, this crate draws no panels, no layouts and no
widgets. It does not enter the alternate screen, does not take over the
terminal, does not read key events, and has no event loop. There is no
ratatui in its dependency graph.
What it has is three things a line-oriented CLI needs: a prompt
sequence, two output renderers and a status line. If you want a
dashboard, a file browser or anything that repaints a region, this is
the wrong crate and ratatui is the right one.
There are no Cargo features¶
Cargo.toml declares no [features] table at all. Consequences:
default-features = falsedoes nothing.- You cannot take the wizard without also compiling the render helpers and the spinner.
- You cannot drop
miette,serde_jsonortabledfrom your dependency graph while using any part of the crate.
Depending on rtb-tui means taking all three components and all eight
runtime dependencies. miette with its fancy feature is the largest
of them, and it is not optional.
The wizard only moves one step at a time¶
Back navigation decrements the step index by one. There is no
jump-to-step, no "return to summary", no skipping forward over a step
already answered, and no conditional branching between steps — the step
list is a Vec walked in registration order.
A wizard that needs to branch has to model the branch inside a step: one step that asks a question and then asks the follow-ups itself, rather than two steps the driver chooses between.
The wizard keeps no history and rolls nothing back¶
There is no snapshot of the state at each step and no undo. Going back re-runs the earlier step against the state as it stands now, including anything written by later steps.
So a step that appends — state.items.push(..) — will append again
every time the user visits it. Steps must be idempotent, and nothing in
the type system enforces that.
There is also no persistence: a wizard cannot be saved half-finished
and resumed later. Wizard::run either returns the completed state or
an error.
The builder panics instead of failing to compile¶
WizardBuilder::build panics with Wizard::builder requires
.initial(...) if you never called initial. It is not a typestate
builder and it does not return a Result — the mistake surfaces at
runtime.
The rustdoc claims a typed replacement arrived in v0.2. At 0.6.3 it has not.
Table output has one style and no options¶
render_table applies Style::psql() and nothing else. There is no
theming, no colour, no column-width control, no sorting, no pagination
and no way to change the separator. See
Why the table style is not configurable.
Nested data is the practical limit. Serialize handles a struct inside
a struct; Tabled does not without a per-field attribute telling it
how to flatten. A row type built for JSON will not always render as a
table.
There are only two output formats¶
Text and JSON. No YAML, no CSV, no TSV, no templating, no newline-delimited JSON. Adding a third format means writing it in your own crate — the helpers are not extensible and there is no renderer trait to implement.
The spinner does not spin¶
One static glyph, redrawn only when you call set_message. No frame
animation, no timer, no background task, no percentage, no progress
bar, no elapsed-time display, no multi-line or nested progress. See
Why the spinner does not animate.
It also writes only to stderr, and that is not configurable — there is no way to point it at stdout or at an arbitrary writer.
The spinner cannot be tested against a real terminal¶
The TTY check reads the real console::Term::stderr() and there is no
injection point. Under cargo test stderr is captured, so the spinner
is always inert and the drawing path is never exercised by the suite.
The tests assert that nothing panics, not that anything is rendered.
Errors do not chain¶
WizardError::Step stores the failing step's name and the underlying
error's message, both as String. The original InquireError is
dropped, so there is no source() to walk and no way to match on the
original variant from outside the step.
RenderError::Json is the same shape — a stringified
serde_json::Error, not the error itself.
The declared MSRV is not tested¶
Cargo.toml says rust-version = "1.82". rust-toolchain.toml pins
1.97.1, and every CI job uses the pin, so nothing in this repository
ever compiles the crate on 1.82. Treat the MSRV as intent rather than a
verified guarantee.
The crate knows nothing about your CLI framework¶
No command registration, no configuration loading, no logging, no
dependency injection, no argument parsing. It takes a state type and a
slice of rows and returns strings and errors. Wiring it to a flag, a
config key or a log line is your code's job — and deny.toml bans a
dependency back on rust-tool-base, so it will stay that way.