Item 31: Take advantage of the tooling ecosystem
The Rust ecosystem has a rich collection of additional tools, which provide functionality above and beyond the essential task of converting Rust into machine code.
When setting up a Rust development environment, you're likely to want most of the following basic tools:1
- The
cargo
tool for organizing dependencies (Item 25) and driving the compiler - The
rustup
tool, which manages the installed Rust toolchains - An IDE with Rust support, or an IDE/editor plug-in like
rust-analyzer
, that allows you to quickly navigate around a Rust codebase, and provides autocompletion support for writing Rust code - The Rust playground, for standalone explorations of Rust's syntax and for sharing the results with colleagues
- A bookmarked link to the documentation for the Rust standard library
Beyond these basics, Rust includes many tools that help with the wider task of maintaining a codebase and improving the
quality of that codebase. The tools that are included in the
official Cargo toolchain cover various essential tasks beyond the basics of cargo build
, cargo test
, and cargo run
, for example:
cargo fmt
: Reformats Rust code according to standard conventions.cargo check
: Performs compilation checks without generating machine code, which can be useful to get a fast syntax check.cargo clippy
: Performs lint checks, detecting inefficient or unidiomatic code (Item 29).cargo doc
: Generates documentation (Item 27).cargo bench
: Runs benchmarking tests (Item 30).cargo update
: Upgrades dependencies to the latest versions, selecting versions that are compliant with semantic versioning (Item 21) by default.cargo tree
: Displays the dependency graph (Item 25).cargo metadata
: Emits metadata about the packages that are present in the workspace and their dependencies.
The last of these is particularly useful, albeit indirectly: because there's a tool that emits information about crates
in a well-defined format, it's much easier for people to produce other tools that make use of that information
(typically via the cargo_metadata
crate, which provides
a set of Rust types to hold the metadata information).
Item 25 described some of the tools that are enabled by this metadata availability, such as cargo-udeps
(which
allows detection of unused dependencies) or cargo-deny
(which allows checks for many things, including
duplicate dependencies, allowed licenses, and security advisories).
The extensibility of the Rust toolchain is not just limited to package metadata; the compiler's abstract syntax
tree can also be built upon, often via the
syn
crate. This information is what makes procedural macros (Item 28) so potent but
also powers a variety of other tools:
cargo-expand
: Shows the complete source code produced by macro expansion, which can be essential for debugging tricky macro definitions.cargo-tarpaulin
: Supports the generation and tracking of code coverage information.
Any list of specific tools will always be subjective, out of date, and incomplete; the more general point is to explore the available tools.
For example, a search for cargo-<something>
tools gives dozens of
results; some will be inappropriate and some will be abandoned, but some might just do exactly what you want.
There are also various efforts to apply formal verification to Rust code, which may be helpful if your code needs higher levels of assurance about its correctness.
Finally, a reminder: if a tool is useful on more than a one-off basis, you should integrate the tool into your CI system (as per Item 32). If the tool is fast and false-positive free, it may also make sense to integrate the tool into your editor or IDE; the Rust Tools page provides links to relevant documentation for this.
Tools to Remember
In addition to the tools that should be configured to run over your codebase regularly and automatically (Item 32), there are various other tools that have been mentioned elsewhere in the book. For reference, these are collated hereābut remember that there are many more tools out there:
- Item 16 recommends the use of Miri when writing subtle
unsafe
code. - Item 21 and Item 25 include mention of Dependabot, for managing dependency updates.
- Item 21 also mentions
cargo-semver-checks
as a possible option for checking that semantic versioning has been done correctly. - Item 28 explains that
cargo-expand
can help when debugging macro problems. - Item 29 is entirely dedicated to the use of Clippy.
- The Godbolt compiler explorer allows you to explore the machine code corresponding to your source code, as described in Item 30.
- Item 30 also mentions additional testing tools, such as
cargo-fuzz
for fuzz testing andcriterion
for benchmarking. - Item 35 covers the use of
bindgen
for auto-generating Rust FFI wrappers from C code.
This list may be reduced in some
environments. For example, Rust development in Android has a centrally controlled
toolchain (so no rustup
) and integrates with Android's Soong build system (so no cargo
).