Rust Crates and External Dependencies

About This Module

This module introduces Rust's package management system through crates, which are reusable libraries and programs. Students will learn how to find, add, and use external crates in their projects, with hands-on experience using popular crates like rand, csv, and serde. The module covers the distinction between binary and library crates, how to manage dependencies in Cargo.toml, and best practices for working with external code.

Prework

Before this lecture, please read:

Pre-lecture Reflections

  1. What is the difference between a package, crate, and module in Rust?
  2. How does Cargo manage dependencies and versions?
  3. Why might you choose to use an external crate versus implementing functionality yourself?

Learning Objectives

By the end of this lecture, you should be able to:

  • Distinguish between binary and library crates
  • Add external dependencies to your Rust project using Cargo.toml
  • Use popular crates like rand, csv, and serde in your code
  • Understand semantic versioning and dependency management
  • Evaluate external crates for trustworthiness and stability

What are crates?

Crates provided by a project:

  • Binary Crate: Programs you compile to an executable and run.
    • Each must have a main() function that is the program entry point
    • So far we have seen single binaries
  • Library Crate: Define functionality than can be shared with multiple projects.
    • Do not have a main() function
    • A single library crate: can be used by other projects

Shared crates

Where to find crates:

  • Official list: crates.io
  • Unofficial list: lib.rs (including ones not yet promoted to crates.io)

Documentation:

Crate rand: random numbers

See: crates.io/crates/rand

Tell Rust you want to use it:

  • cargo add rand for the latest version
  • cargo add rand --version="0.8.5" for a specific version
  • cargo remove rand to remove it

This adds to Cargo.toml:

[dependencies]
rand = "0.8.5"

Note: Show demo in VS Code.

Question: Why put the version number in Cargo.toml?

To generate a random integer from 1 through 100:

extern crate rand; // only needed in mdbook
use rand::Rng;

fn main() {
  let mut rng = rand::rng();
  let secret_number = rng.random_range(1..=100);
  println!("The secret number is: {secret_number}");
}

Useful Crates

  • csv: reading and writing CSV files
  • serde: serializing and deserializing data
  • serde_json: serializing and deserializing JSON data

See: crates.io/crates/csv See: crates.io/crates/serde See: crates.io/crates/serde_json