Item 31: Take advantage of the tooling ecosystem

The Rust ecosystem has a rich collection of additional tools above and beyond the essential task of converting Rust into machine code, many of which help with the wider task of maintaining a codebase, and improving the quality of that codebase.

The tools that are present 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 quick 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 compliant with semantic versioning (Item 21).
  • cargo tree displays the dependency graph (Item 25).
  • cargo metadata emits metadata about the packages 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, for example:

  • 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, 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 continuous integration system (as per Item 32).