Rust Code Styling with rustfmt & cargo fmt | Web Formatter Blog

Rust Code Styling with rustfmt & cargo fmt
A comprehensive guide to formatting Rust code automatically for better readability and consistency.
Introduction to Rust Code Formatting
Consistent code formatting is essential for any programming
language, and Rust is no exception. Well-formatted code improves
readability, makes collaboration easier, and helps catch potential
bugs early. Fortunately, the Rust ecosystem provides excellent
tools for automatic code formatting: rustfmt
and{" "}
cargo fmt
.
In this comprehensive guide, we'll explore how to use these tools to maintain consistent code style across your Rust projects, from simple scripts to large-scale applications.
Why Format Your Rust Code?
Beyond just making your code look prettier, there are several compelling reasons to use automatic formatting:
- Consistency: Ensures uniform style across your codebase, even with multiple contributors
- Readability: Makes code easier to understand and maintain
- Productivity: Eliminates time spent debating style choices or manually formatting code
- Community standards: Aligns with Rust's community conventions
- Error prevention: Can help identify potential structural issues
- Easier code reviews: Focuses reviews on logic rather than style
The Rust community has largely converged on a standard style, which is encoded in the default settings of rustfmt. By using rustfmt, you're adopting a style that will be familiar to most Rust developers.
Understanding rustfmt
rustfmt
is Rust's official code formatter. It's
designed to format Rust code according to style guidelines with
minimal configuration. While it allows for some customization, it
intentionally limits options to promote a consistent style across
the Rust ecosystem.
cargo fmt
is a convenience wrapper around rustfmt
that's integrated with Cargo, Rust's package manager. It makes it
easy to format all Rust files in a Cargo project with a single
command.
Both tools reformat your code automatically according to a set of rules, saving you from having to manually adjust whitespace, indentation, line breaks, and other stylistic elements.
Installation
Installing with rustup
The easiest way to install rustfmt is through rustup, the Rust toolchain installer:
rustup component add rustfmt
This installs rustfmt and cargo fmt for the current toolchain. If you switch between different Rust versions using rustup, you'll need to install rustfmt for each version you use.
Building from source
For the latest features or specific versions, you can build rustfmt from source:
git clone https://github.com/rust-lang/rustfmt.git
cd rustfmt
cargo build --release
The compiled binary will be at{" "}
./target/release/rustfmt
. You can add this to your
PATH or copy it to a location that's already in your PATH.
Basic Usage
rustfmt command
To format a single Rust file:
rustfmt path/to/file.rs
This will format the file in-place. If you want to see what changes would be made without modifying the file:
rustfmt --check path/to/file.rs
To output the formatted code to stdout instead of modifying the file:
rustfmt path/to/file.rs --emit stdout
cargo fmt command
To format all Rust files in a Cargo project:
cargo fmt
This command formats all .rs
files in the current
project. To check if files are properly formatted without
modifying them (useful for CI):
cargo fmt -- --check
The double dash (--
) passes the following arguments
to rustfmt.
Configuration Options
rustfmt.toml file
rustfmt can be configured using a rustfmt.toml
file
in your project's root directory. This file contains key-value
pairs specifying formatting options:
# A basic rustfmt.toml file
max_width = 100
tab_spaces = 4
edition = "2021"
reorder_imports = true
rustfmt will look for this file in the current directory and all parent directories, stopping when it finds one.
Common configuration options
Here are some commonly used configuration options:
Option | Default | Description |
---|---|---|
max_width
|
100 | Maximum width of each line |
tab_spaces
|
4 | Number of spaces per indentation level |
edition
|
2015 | Rust edition to use |
newline_style
|
Auto | Line ending style (Unix/Windows/Native) |
use_small_heuristics
|
Default | Whether to use heuristics for fitting code on a single line |
imports_granularity
|
Preserve | How to group imports (Preserve/Crate/Module/Item) |
reorder_imports
|
true | Whether to reorder import statements alphabetically |
For a complete list of configuration options, consult the{" "} rustfmt documentation .
Edition-specific configuration
Different Rust editions (2015, 2018, 2021) have slightly different formatting conventions. You can specify which edition to use:
# Use Rust 2021 edition formatting
edition = "2021"
This is particularly important for features like async/await syntax that were introduced in newer editions.
Code Examples
Let's look at some practical examples of how rustfmt transforms code:
Formatting structs and enums
Formatting functions
Formatting macros
Formatting imports
IDE Integration
rustfmt integrates well with most popular IDEs and text editors, enabling automatic formatting on save or on-demand.
VSCode integration
For Visual Studio Code, install the "Rust" extension (rust-lang.rust-analyzer), which includes rustfmt integration. Configure it in your settings.json:
{
"editor.formatOnSave": true,
"rust-analyzer.rustfmt.rangeFormatting.enable": true,
"rust-analyzer.checkOnSave.command": "clippy"
}
With these settings, your Rust code will be formatted automatically whenever you save a file.
IntelliJ Rust integration
The IntelliJ Rust plugin includes rustfmt integration. To configure it:
- Go to Settings/Preferences {">"} Languages & Frameworks {">"}{" "} Rust {">"} Rustfmt
- Check "Run rustfmt on Save"
- Set the path to the rustfmt binary if needed
You can also run rustfmt manually with the "Reformat Code" action (usually Ctrl+Alt+L or Cmd+Option+L).
Vim and Emacs integration
For Vim, you can use the vim-rust plugin or configure an external formatter:
" In your .vimrc
autocmd BufWrite *.rs :silent !rustfmt %
For Emacs, the rustic or rust-mode packages include rustfmt integration:
;; In your .emacs or init.el
(setq rustic-format-on-save t)
CI/CD Integration
Adding rustfmt checks to your CI/CD pipeline helps ensure that all code being merged or deployed follows your formatting guidelines.
GitHub Actions
Here's a sample GitHub Actions workflow that checks code formatting:
name: Rust Format Check
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
components: rustfmt
override: true
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
This workflow will fail if any file isn't properly formatted, encouraging consistent style across your codebase.
GitLab CI
For GitLab CI, add a formatting check to your .gitlab-ci.yml:
rustfmt:
image: rust:latest
stage: lint
script:
- rustup component add rustfmt
- cargo fmt -- --check
only:
- merge_requests
Troubleshooting
Common issues
Here are some common problems you might encounter with rustfmt and how to solve them:
- Formatting creates strange line breaks: This often happens with long expressions. Consider refactoring your code into smaller functions or using intermediate variables.
-
Some parts of the code aren't formatted:
rustfmt respects
#[rustfmt::skip]
attributes. Check if these are present, or if there are syntax errors preventing proper formatting. - Formatting inconsistently applied across the project : Ensure everyone on the team is using the same rustfmt version and configuration.
Version mismatches
rustfmt is still evolving, and different versions might format code differently. To ensure consistency across your team and CI:
- Specify a rustfmt version in your project documentation
- Consider pinning the rustfmt version in your CI configuration
-
Always run
cargo fmt
before submitting pull requests
To check your installed rustfmt version:
rustfmt --version
Best Practices
To get the most out of rustfmt:
- Run rustfmt regularly, ideally before committing code, to maintain consistent style throughout development
- Use a consistent configuration across your team by checking in your rustfmt.toml file
- Configure your editor for automatic formatting to make it a seamless part of your workflow
- Add a formatting check to your CI pipeline to catch style issues early
- Focus on code organization rather than manual formatting—let rustfmt handle the details
- Periodically review configuration as your project evolves and rustfmt adds new options
Conclusion
rustfmt and cargo fmt are invaluable tools in the Rust ecosystem, promoting consistent code style with minimal effort. By integrating these tools into your development workflow, you can focus on writing functionality rather than manually formatting code.
Remember that while formatting is important, it's just one aspect of code quality. Combine rustfmt with other tools like clippy (the Rust linter) and comprehensive tests to ensure your code is not just well-formatted, but also correct and maintainable.
As the Rust language continues to evolve, so too will rustfmt. Stay updated with the latest recommendations and features to keep your codebase clean, consistent, and idiomatic.