Pipecircuit visualization
pipecircuit-visualization derives reviewable architecture diagrams from a
crate's Rust source. It walks the crate's module tree, finds every explicit
StateMachine and StepInputOf implementation, follows imports, and expands
each outcome enum into its variants.
No diagram-specific step list is maintained:
use ;
let architecture = read?;
let players = architecture.state_machine?;
let snapshot = players.render;
The uncolored text tree is intended for expect tests and redirected output.
AnsiTextTree gives its role markers a terminal-safe lime treatment. The same
graph can be projected to MermaidFlowchart for Markdown and browser tooling
or GraphvizDot for Graphviz, SVG, and image generation.
The separately installable pipecircuit-cli package exposes the interactive
surface:
pipec diagram Players
It selects ANSI text only for an interactive terminal and honors NO_COLOR.
Generation fails when a referenced local type, module, state machine, input,
or outcome cannot be resolved. Procedural macros that generate
StepInputOf implementations are not source-visible on stable Rust and are
not currently supported; step implementations themselves must remain ordinary
Rust. This keeps incomplete diagrams from masquerading as complete ones.
Behavior expectations
Keep a behavior.rs snapshot module beside a machine's tests and architecture
expectation. Its inventory discovers the compiled tests automatically:
use expect;
use ;
Register this dedicated child module with #[cfg(test)] mod behavior;. The
inventory includes tests below its parent module and excludes its own module.
Renaming, adding, or removing a check changes the expectation. Review the diff,
then accept it with UPDATE_EXPECT=1 cargo test behavior_remains_reviewable.
Discovery asks the current test executable for its list; it neither reruns
the checks nor starts Cargo. Macro-generated tests, including property tests,
are included. Names become alphabetically sorted sentence bullets; duplicate
sentences retain their code locations, and ignored tests carry [ignored].
This is a review aid, not evidence that a named claim passed. The ordinary verification run supplies that evidence. Discovery covers only the current libtest target and compiled features: other test targets, doctests, and Kani proof harnesses are not included. No production dependency or runtime instrumentation is needed in a consuming application's semantic core; use this library as a dev-dependency.
Browser-only checks need a host-side snapshot: the browser cannot launch a test executable or update source files. Supply a configured listing command to the same inventory instead of reimplementing discovery or rendering. Mount the snapshot under the same relative module hierarchy in the host harness:
use Command;
let mut runner = new;
runner.current_dir.args;
let inventory = for_snapshot_with_runner?;
For example, a browser snapshot at wiring::tests::behavior must remain a
behavior child of wiring::tests in the host harness, not be flattened into
a differently named module. The crate-name prefix may differ; the relative
module path determines the scope. No handwritten qualified scope is needed.
The helper appends the standard listing flags and queries all checks and
ignored checks separately.
WASM discovery lists compiled exports without starting a browser; run the
actual browser suite independently to verify those claims. Keep runner setup
in the host test harness and the expectation in behavior.rs beside its
owning browser tests. The existing UPDATE_EXPECT=1 workflow is unchanged.
Compiled program and installation views
Experimental development scaffolding — not ready for application consumption. These rudimentary views support framework review. Their APIs and presentation need further design; expansion is deferred while authoring and performance work progress. This status applies to program/installation inspection, not the existing state-machine architecture and behavior tooling above.
pipe_roster! derives DescribeRoster from the named pipe declarations.
Roster-bound MioPipeSet records derive DescribeBindings from the actual
installed fields. Inspection therefore needs no parallel inventory:
let program = ;
let semantic = program.render;
let physical = program.installed.render;
The board must use the selected roster, and the bindings must name that same
roster. Text, Mermaid and Graphviz include pipe families, carrier types and
package/file/line/column locations. Rendered type names abbreviate module paths;
pipes() and bindings() preserve qualified diagnostic labels. Compiler type
names are not stable protocol identifiers or wire revisions. This renderer
currently emits plain text for both text targets.
These are declared boundary views, not inferred route or reachability graphs. Switchboard decisions, remote placement, compatibility and transport health cannot be deduced from Rust type names. Dashed graph edges identify the In/Out families and installation relation only.
The underlying metadata iterators and Mio ready_sources().statuses() borrow
existing structures or return fixed-size values, without allocation. Source
statuses expose retained activation hints and ready/paused state, in storage
order; inspecting them neither dispatches nor resumes work. An absent source
is not evidence of a healthy pipe. The source table's capacity bounds this
observation, not the occupancy of every transport queue.
ProgramDiagram and its renderers allocate in this optional std tooling crate.
Use them in development tools or examples, outside measured steady-state work.
Keep pipecircuit-visualization a dev-dependency when semantic libraries must
remain no_std.
For a directly usable browser artifact, call render_html() on either view and
write the returned string to an HTML file. The standalone page works offline,
uses native disclosure controls for exact types and declaration locations, and
can hide the physical layer while preserving the logical pipes. It requires no
JavaScript, Mermaid installation or web service. Text, HTML and graph views name
message directions from each pipe's perspective: emits to the switchboard (Out),
receives from the switchboard (In).
Ordinary Rust documentation on roster roles and installed fields travels with the compiled metadata. Write the role's purpose beside its declaration and describe physical choices beside the installed field. These descriptions explain the structure; they are not proofs of behavior. HTML treats them as plain escaped text, including documentation containing markup. Optional tooling allocates to render them; metadata iteration still uses static strings and fixed arrays.