What's here
As of v0.2.5, the output layer is implemented and stable — the load-bearing
piece every sibling crate in the cli collection depends on:
- Plain output —
out/err: one call, no parsing, no allocation for a string literal. The hot path stays cheap. - Three styling paths — a chainable
stylebuilder, inlineparsetags, and a nameddefine_tag/tagregistry. All three render to identical bytes for the same intent. - Full color — the eight standard names plus any 24-bit color via hex or RGB,
with graceful downgrade to 256- or 16-color terminals and clean fall-back to
plain text on pipes,
NO_COLOR, or the Windows console without ANSI.
The command tree, runtime registration, help engine, and auth seam land across the
rest of the 0.x series — see the ROADMAP.
Installation
[]
= "0.2"
Color is on by default. For a build that never emits escape sequences (the API stays complete; every styled value renders as its plain text):
[]
= { = "0.2", = false, = ["std"] }
Quick Start
use ;
// Plain output — the common case.
out;
err;
// Styling, three ways, all rendering to the same bytes for the same intent:
out; // builder
parse; // inline tags
define_tag; // named registry
out;
The three styling paths
The same styled line, produced three ways. The choice is ergonomic, not visual — the bytes are identical.
use ;
// 1. Builder — chain methods; the result is `Display`. Best for computed/one-off.
out;
// 2. Tags — one string with inline markup. Best when text and style live together.
parse;
// 3. Named registry — define the look once, reuse by name across the program.
define_tag;
out;
Tag grammar: <b>…</b> (bold), <u>…</u> (underline),
<c=VALUE>…</c> (color, where VALUE is a named color, #rrggbb, or r,g,b),
and </> to close the innermost tag. Tags nest; unrecognized tags print
literally, so parse never rejects input.
Colors and terminals
Colors are the eight standard names, plus any 24-bit value:
use ;
out;
out;
out;
The terminal's capability is detected once. A 24-bit color renders exactly on a
true-color terminal, downgrades to the nearest 256- or 16-color value where that
is all the terminal supports, and falls away to plain text when output is a pipe,
NO_COLOR is set, or the crate is built without color. CLICOLOR_FORCE
overrides detection and forces color on. The Windows console is handled behind the
same API — virtual-terminal mode is enabled automatically, with a plain-text
fall-back if it cannot be.
Feature flags
| Feature | Default | Description |
|---|---|---|
std |
yes | Standard library: terminal detection and the stdout/stderr writers. |
color |
yes | ANSI / styled output. Implies std. Disable for plain output (still complete). |
auth |
no | Reserved for the requires_auth command flag (v0.5.0); no effect yet. |
Examples
Runnable examples live in examples/:
Force color when output is captured, or disable it, to see both paths:
CLICOLOR_FORCE=1
NO_COLOR=1
Performance
The plain path is allocation-free for a string literal — proven by a
counting-allocator test (tests/allocation.rs), not asserted. Local Criterion
means (Windows x86_64, release build):
| Operation | ns/op |
|---|---|
out plain write (&str) |
~10 |
| builder render, named color + bold | ~50 |
| builder render, 24-bit color | ~75 |
| named-registry render | ~43 |
Styling costs more than the plain path because it builds an owned String and
encodes escape sequences — a cost paid only when you opt into color. Reproduce
with cargo bench --bench bench.
Status
v0.2.5 ships the output layer per the ROADMAP and
docs/API.md. The command tree and runtime registration
(v0.3.0), the help engine (v0.4.0), and the auth seam (v0.5.0) follow; the
public API freezes at 1.0.0.
Contributing
See dev/DIRECTIVES.md for engineering standards and the definition of done. Before a PR: cargo fmt --all, cargo clippy --all-targets --all-features -- -D warnings, and cargo test --all-features must be clean.