How to Use the topcoat fmt CLI to Format view! Macros
The topcoat fmt command reformats Topcoat macro bodies by first piping them through rustfmt and then applying a custom pretty-printer to normalize HTML-like syntax in view! and related macros.
The topcoat fmt CLI is the official formatting tool for the Topcoat UI framework, designed specifically to handle the unique syntax of declarative macros. According to the tokio-rs/topcoat source code, this tool performs a two-stage formatting process that applies standard Rust style rules followed by Topcoat-specific indentation and spacing conventions.
How the Two-Stage Formatter Works
The formatter implemented in crates/topcoat-cli/src/fmt.rs processes macro bodies through two distinct phases to ensure consistent output.
Stage 1: Rust Code Formatting
First, the tool pipes the macro body through rustfmt, applying standard Rust style rules to all embedded Rust expressions. This ensures that control-flow constructs like if, for, match, and let blocks follow canonical Rust formatting.
Stage 2: Topcoat-Specific Pretty-Printing
After rustfmt completes, a custom pretty-printer reformats the HTML-like syntax of view! blocks and related macros. This stage handles tag indentation, attribute spacing, and expression braces to produce consistent markup alignment. The implementation correctly manages interpolated Rust expressions ({expr}), nested components, and attribute forwarding.
Supported Macros and Syntax
The formatter recognizes and reformats all Topcoat declarative macros, including:
view!- Primary template macro for HTML-like markupcomponent!- Component definition macroattributes!- Attribute grouping macroclass!- CSS class utility macroprops!- Property declaration macro
As documented in crates/topcoat-view/macro/docs/view.md and crates/topcoat-view/macro/docs/component.md, the formatter understands the specific grammar rules for each macro variant.
Command-Line Options
The topcoat fmt command, registered in crates/topcoat-cli/src/main.rs, accepts several flags to control formatting behavior:
--check- Verifies formatting without writing changes; exits with non-zero status if any macro body needs changes, making it ideal for CI pipelines--write- Formats files and writes changes back to disk (default behavior)--path <PATH>- Restricts formatting to a specific file or directory relative to the current working directory--quiet- Suppresses diagnostic output, printing only errors--verbose- Displays each file being processed during execution
By default, the command walks the entire Cargo workspace, but you can limit scope using the --path flag.
Usage Examples
Format the entire workspace:
topcoat fmt
Verify formatting in CI (check-only mode):
topcoat fmt --check
Format a specific crate or file:
topcoat fmt --path examples/simple
topcoat fmt --path src/main.rs
Run quietly with verbose error reporting:
topcoat fmt --quiet
Formatting Results
Consider the following unformatted view! macro in src/views.rs:
view! {
div class="container"{
if let Some(user)=cx.user(){
p {"Welcome, " {user.name} "!"}
}else{
p {"Please log in"}
}
}
}
After running topcoat fmt, the output becomes:
view! {
div class = "container" {
if let Some(user) = cx.user() {
p { "Welcome, " { user.name } "!" }
} else {
p { "Please log in" }
}
}
}
The formatter applies consistent four-space indentation, adds spaces around assignment operators, and normalizes brace spacing for interpolated expressions.
Key Implementation Files
The formatting logic is distributed across these critical paths in the tokio-rs/topcoat repository:
crates/topcoat-cli/src/fmt.rs- Core implementation of thetopcoat fmtcommand, containing the argument parser, workspace walker, and two-stage formatting orchestrationcrates/topcoat-cli/docs/fmt.md- Official user documentation describing CLI flags and CI integration patternscrates/topcoat-view/macro/docs/view.md- Syntax specification forview!macro formatting targetscrates/topcoat-view/macro/docs/component.md- Component macro syntax documentationcrates/topcoat-cli/src/main.rs- Binary entry point that registers thefmtsubcommand
Summary
- Two-stage process:
topcoat fmtrunsrustfmtfirst, then applies Topcoat-specific pretty-printing rules to macro bodies - Multi-macro support: Handles
view!,component!,attributes!,class!, andprops!macros with syntax-aware formatting - CI integration: Use
--checkfor non-destructive verification in continuous integration pipelines - Flexible targeting: Format entire workspaces or limit scope to specific files via
--path - Source locations: Implementation resides in
crates/topcoat-cli/src/fmt.rswith documentation incrates/topcoat-cli/docs/fmt.md
Frequently Asked Questions
Does topcoat fmt modify files in-place by default?
Yes, the default behavior is --write, which reformats and overwrites source files directly. To verify formatting without modifying files, use the --check flag, which reports violations without writing changes and exits with a non-zero status if formatting is needed.
Can I use topcoat fmt in CI pipelines?
Absolutely. Run topcoat fmt --check in your CI workflow to enforce formatting standards. This command fails the build if any view! or related macro bodies do not match the expected format, preventing unformatted code from merging into your main branch.
Which Topcoat macros does the formatter support?
The formatter supports all Topcoat declarative macros including view!, component!, attributes!, class!, and props!. As implemented in crates/topcoat-cli/src/fmt.rs, it recognizes these macro invocations and applies appropriate formatting rules for each syntax variant.
How does topcoat fmt handle Rust expressions inside view! macros?
The tool correctly processes interpolated Rust expressions ({expr}) and control-flow constructs by first running them through rustfmt. This ensures that if let, for loops, match statements, and variable assignments inside macro bodies receive standard Rust formatting before the Topcoat pretty-printer applies markup-specific styling.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →