10 Awesome Rust Crates and Resources to Learn
Tags: rust, productivity
Published: 2020-08-30 17:39:25

---
title: 10 Awesome Rust Crates and Resources to Learn
published: true
description: These crates are a great list of things to explore the rust community and learn from
tags: [rust,productivity]
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/c4yj0u1smgr9f3ctg5c3.png
---

If you're just getting started in Rust, you might wonder what kind of packages you should be exploring and how to get started in the community. Depending on your initial use case, here are a few resources I have found to be immensely helpful in learning rust. Enjoy!

## The Definitive Book

> Affectionately nicknamed “the book,” The Rust Programming Language will give you an overview of the language from first principles. You’ll build a few projects along the way, and by the end, you’ll have a solid grasp of the language.

https://doc.rust-lang.org/book/

All rustaceans need to make sure they read through this before they go anywhere else. It's the best guide there is on learning the language and it's practically everyone's starting point.

## 1. Crate: [nom](https://github.com/Geal/nom)

![nom](https://dev-to-uploads.s3.amazonaws.com/i/nk9lt8foewi1b4ayzu6o.png)

> nom is a parser combinators library written in Rust. Its goal is to provide tools to build safe parsers without compromising the speed or memory consumption. To that end, it uses extensively Rust's strong typing and memory safety to produce fast and correct parsers, and provides functions, macros and traits to abstract most of the error prone plumbing.

I was once trying to implement a simple netflow parser and I came across `nom`. The ergonomics for implementing protocols is straightforward and it includes a number of helpful examples. Here's an example of a color parser!

```rust
extern crate nom;
use nom::{
  IResult,
  bytes::complete::{tag, take_while_m_n},
  combinator::map_res,
  sequence::tuple
};

#[derive(Debug,PartialEq)]
pub struct Color {
  pub red:   u8,
  pub green: u8,
  pub blue:  u8,
}

fn from_hex(input: &str) -> Result<u8, std::num::ParseIntError> {
  u8::from_str_radix(input, 16)
}

fn is_hex_digit(c: char) -> bool {
  c.is_digit(16)
}

fn hex_primary(input: &str) -> IResult<&str, u8> {
  map_res(
    take_while_m_n(2, 2, is_hex_digit),
    from_hex
  )(input)
}

fn hex_color(input: &str) -> IResult<&str, Color> {
  let (input, _) = tag("#")(input)?;
  let (input, (red, green, blue)) = tuple((hex_primary, hex_primary, hex_primary))(input)?;

  Ok((input, Color { red, green, blue }))
}

fn main() {}

#[test]
fn parse_color() {
  assert_eq!(hex_color("#2F14DF"), Ok(("", Color {
    red: 47,
    green: 20,
    blue: 223,
  })));
}
```

In the repository you will find parsers for just about anything from programming languages, network protocols, misc formats like gameboy roms, and text formatting. Definitely worth looking at or keeping as a bookmark.

## 2. Crate: [Bevy Game Engine](https://bevyengine.org)

![Bevy](https://dev-to-uploads.s3.amazonaws.com/i/009xqbpxdf69qghp146i.gif)

Bevy is an amazing game engine crate! It provides a number of fantastic out of the box tooling and features such as:

* Cross Platform: Windows, MacOS, and Linux (with planned support for mobile and web)
* 3D: Lights, meshes, textures, MSAA, and GLTF loading
* Sprites: Render individual images as sprites, render from sprite sheets, and dynamically generate new sprite sheets
* Assets: An extensible, event driven asset system that loads assets asynchronously in background threads
* Scenes: Save ECS Worlds to human-readable scene files and load scene files into ECS Worlds
* Plugins: All engine and app features are implemented as modular plugins
* Sound: Load audio files as assets and play them from within systems
* Multiple Render Backends: Vulkan, DirectX 12, and Metal (with more on the way thanks to wgpu)
* Data Driven Shaders: Easily bind ECS components directly to shader uniforms
* Hot Asset Reloading: Automatically reload changes to assets at runtime without recompiles or restarts
* Events: Efficiently consume and produce Events from within ECS systems
* Properties: Dynamically get and set component fields using a string version of their names
* Hierarchical Transforms: Create parent-child relationships between entities that propagate Transforms down the hierarchy

The design goals are to keep things very simple for newcomers while providing a lot of flexibility for seasoned developers. The ergonomics and compilation performance is really something to marvel at!

## 3. Crate: [rocket.rs web framework](https://rocket.rs/)

If you need to write a web site without sacrificing type safety, flexibility, and usability - then take a look at rocket.rs. I've tried using a number of different web frameworks from including [actix-web](https://actix.rs/), [tide](https://github.com/http-rs/tide), and [warp](https://github.com/seanmonstar/warp). There is much debate over the ecosystem here, but I think in the end I would have to put [rocket.rs](https://rocket.rs) in this list.

```rust
#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use] extern crate rocket;

#[get("/hello/<name>/<age>")]
fn hello(name: String, age: u8) -> String {
    format!("Hello, {} year old named {}!", age, name)
}

fn main() {
    rocket::ignite().mount("/", routes![hello]).launch();
}
```

If you want a better overview and comparison between the different web frameworks and ergonomics check out this post by [Luca Palmieri](https://www.lpalmieri.com/posts/2020-07-04-choosing-a-rust-web-framework-2020-edition/) on [Choosing a Rust Web Framework 2020 Edition](https://www.lpalmieri.com/posts/2020-07-04-choosing-a-rust-web-framework-2020-edition/).

## 4. Crate/Ecosystem: [Tokio.rs](https://tokio.rs/tokio/tutorial)

Tokio is an async runtime for the Rust programming language. There is some debate at the long term [differences between the async-std](https://www.reddit.com/r/rust/comments/i5hppj/smol_vs_tokio_vs_asyncstd/) but in any case, tokio is quite a powerhouse and you can't go very far without running into tokio dependencies in many rust crates.

Here is the starter for the mini redis tutorial:

```rust
use mini_redis::{client, Result};

#[tokio::main]
pub async fn main() -> Result<()> {
    // Open a connection to the mini-redis address.
    let mut client = client::connect("127.0.0.1:6379").await?;

    // Set the key "hello" with value "world"
    client.set("hello", "world".into()).await?;

    // Get key "hello"
    let result = client.get("hello").await?;

    println!("got value from the server; result={:?}", result);

    Ok(())
}
```

Check it out!

## 5. Crate [serde serialization](https://crates.io/crates/serde)

Serde is a framework for serializing and deserializing Rust data structures into a variety of formats (complimented by things like [serde-json](https://github.com/serde-rs/json)

```rust
use serde::{Deserialize, Serialize};
use serde_json::Result;

#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: u8,
    phones: Vec<String>,
}

fn typed_example() -> Result<()> {
    // Some JSON input data as a &str. Maybe this comes from the user.
    let data = r#"
        {
            "name": "John Doe",
            "age": 43,
            "phones": [
                "+44 1234567",
                "+44 2345678"
            ]
        }"#;

    // Parse the string of data into a Person object. This is exactly the
    // same function as the one that produced serde_json::Value above, but
    // now we are asking it for a Person as output.
    let p: Person = serde_json::from_str(data)?;

    // Do things just like with any other Rust data structure.
    println!("Please call {} at the number {}", p.name, p.phones[0]);

    Ok(())
}
```

Here are a number of [great examples](https://serde.rs/examples.html) on their documentation website!

## 6. Crate: [hyper HTTP](https://hyper.rs/)

hyper is a fast HTTP implementation for Rust

* A **client** for talking to web services
* A **server** for building those web services
* Blazing **fast** thanks to Rust
* High **concurrency** with non-blocking sockets
* HTTP/1 and HTTP/2 support

```rust
use std::{convert::Infallible, net::SocketAddr};
use hyper::{Body, Request, Response, Server};
use hyper::service::{make_service_fn, service_fn};

async fn handle(_: Request<Body>) -> Result<Response<Body>, Infallible> {
    Ok(Response::new("Hello, World!".into()))
}

#[tokio::main]
async fn main() {
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));

    let make_svc = make_service_fn(|_conn| async {
        Ok::<_, Infallible>(service_fn(handle))
    });

    let server = Server::bind(&addr).serve(make_svc);

    if let Err(e) = server.await {
        eprintln!("server error: {}", e);
    }
}
```

This helps if you want to get a bit more lower level than a "web framework" like [warp](https://github.com/seanmonstar/warp) which builds on top of hyper.

## 7. Crate: [textwrap](https://crates.io/crates/textwrap)

If you need a small quick library that knows how to wrap text for command line utilities, take a look at this crate.

```
[dependencies]
textwrap = "0.12"
```

```rust
fn main() {
    let text = "textwrap: a small library for wrapping text.";
    println!("{}", textwrap::fill(text, 18));
}
```

```
textwrap: a small
library for
wrapping text.
```

## 8. Crate: [reqwest HTTP Client](https://crates.io/crates/reqwest)

If you need a more "batteries-included" HTTP request client then take a look at reqwest. Some of the includes features:

* Plain bodies, JSON, urlencoded, multipart
* Customizable redirect policy
* HTTP Proxies
* HTTPS via system-native TLS (or optionally, rustls)
* Cookie Store
* WASM

Here's an example below that uses [tokio.rs](https://tokio.rs) and the async runtime to do a simple `GET` request.

```rust
use std::collections::HashMap;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let resp = reqwest::get("https://httpbin.org/ip")
        .await?
        .json::<HashMap<String, String>>()
        .await?;
    println!("{:#?}", resp);
    Ok(())
}
```

## 9. Crate: [cargo edit: cargo utility](https://crates.io/crates/cargo-edit)

There are a number of helpful utilities you can add to the built-in `cargo` command. The one I like to have is `cargo-edit` which lets you do things like:

### cargo add
```
$ # Add a specific version
$ cargo add regex@0.1.41 --dev
$ # Query the latest version from crates.io and adds it as build dependency
$ cargo add gcc --build
$ # Add a non-crates.io crate
$ cargo add local_experiment --path=lib/trial-and-error/
$ # Add a non-crates.io crate; the crate name will be found automatically
$ cargo add lib/trial-and-error/
$ # Add a crates.io crate with a local development path
$ cargo add my_helper --vers=1.3.1 --path=lib/my-helper/
$ # Add a renamed dependency
$ cargo add thiserror --rename error
```

### cargo rm

```
$ # Remove a dependency
$ cargo rm regex
$ # Remove a development dependency
$ cargo rm regex --dev
$ # Remove a build dependency
$ cargo rm regex --build
```

### cargo upgrade

```
# Upgrade all dependencies for the current crate
$ cargo upgrade
# Upgrade docopt (to ~0.9) and serde (to >=0.9,<2.0)
$ cargo upgrade docopt@~0.9 serde@>=0.9,<2.0
# Upgrade regex (to the latest version) across all crates in the workspace
$ cargo upgrade regex --workspace
```

Super helpful when you don't want to edit `Cargo.toml`

## 10. Crate: [cargo audit: cargo utility](https://crates.io/crates/cargo-audit)

Cargo-audit will audit `Cargo.lock` files for crates with security vulnerabilities reported to the [RustSec Advisory Database](https://github.com/RustSec/advisory-db/). Very helpful!

![Cargo Audit](https://dev-to-uploads.s3.amazonaws.com/i/4f4awvimk2ye34xgug1b.png)


## Conclusion

These are only a small fraction of the vast Rust community out there. If you're looking to explore more, check out these helpful **Awesome Rust** repositories for more!

* https://github.com/rust-unofficial/awesome-rust
* https://github.com/rust-embedded/awesome-embedded-rust

Cheers! 🍻

--

If you liked this article, please feel free to give me a follow and a like. Also check out my [twitter](https://twitter.com/nyxtom) for more updates! 

Thanks again!