Useful Crates and Tools

Rust is not just a language, it is an ecosystem for development with various development tools and crates. cargo is one such example but there are many more tools as well as crates. Here we highlight some of the popular ones.

Crates

A crate refers to a binary or a library in Rust. You may be familiar with it already since cargo creates a binary or library crate in a package. There are many crates out there that are very useful for development.

crates.io & lib.rs

crates.io is a place to find an external crate that you can leverage in your code. All crates available on crates.io have a documentation available on Docs.rs. lib.rs is an alternative to crates.io and provides similar functionality.

serde

serde is a de fact standard serialization library for Rust. It allows you to transform a data structure into a different format (e.g., JSON) and later restore it into the same data structure. serde is highly popular and convenient, and many Rust programs rely on it.

Tokio

Tokio provides an asynchronous runtime for Rust. Asynchrony here means that you make a call and you return right away without waiting until the call finishes. Thus, you can get much better performance than synchronous counterparts. You could also use Async instead.

Logging Crates

Logging is necessary for any kind of development and Rust has good support for it. The most common crate to use is the log crate, which provides an interface. Since the crate only provides an interface, you need to use another crate that provides an implementation, e.g., env_logger.

Command-Line Argument Parsing Crates

Argument parsing is often necessary for programs and Rust has convenient external crates that you can use. clap is one such crate and it is easy to use, and structopt is another popular one.

Tools

Clippy

The first one to highlight is called Clippy, which is a linter that checks your code and catches mistakes or stylistic issues. You can install it with rustup and it is widely popular. Just to show the usefulness of it, here are some of the examples that Clippy can catch.

  • Example 1

    Catches:

    #![allow(unused)]
    fn main() {
    fn func(opt: Option<Result<u64, String>>) {
        let n = match opt {
            Some(n) => match n {
                Ok(n) => n,
                _ => return,
            }
            None => return,
        };
    }
    }
    

    Suggests:

    #![allow(unused)]
    fn main() {
    fn func(opt: Option<Result<u64, String>>) {
      let n = match opt {
          Some(Ok(n)) => n,
          _ => return,
      };
    }
    }
    
  • Example 2

    Catches:

    #![allow(unused)]
    fn main() {
    for i in iter {
      if let Some(value) = i.parse().ok() {
          vec.push(value)
      }
    }
    }
    

    Suggests:

    #![allow(unused)]
    fn main() {
    for i in iter {
      if let Ok(value) = i.parse() {
          vec.push(value)
      }
    }
    }
    
  • Example 3

    Catches:

    #![allow(unused)]
    fn main() {
    fn bar(stool: &str) {}
    let x = Some("abc");
    
    match x {
        Some(ref foo) => bar(foo),
        _ => (),
    }
    }
    

    Suggests:

    #![allow(unused)]
    fn main() {
    fn bar(stool: &str) {}
    let x = Some("abc");
    
    if let Some(ref foo) = x {
        bar(foo);
    }
    }
    

rustfmt

rustfmt is the default code formatter for Rust. You should use it if not already. It is better to integrate it with your editor, e.g., by using a Rust plugin for your editor or through the combination of plugins and rls.

Miri

Miri is a runtime interpreter for Rust that can check some of the problems with your code especially with the unsafe part of your code. You need to use a nightly version of Rust in order to use Miri.

cargo test

Rust has great support for testing via cargo test. You can find the details from the Rust book and the Cargo book.