Cargo, Crates and Basic Project Structure

Cargo

Cargo is Rust’s built-in package manager and the build system. It can be used to,

  • Create a new project: cargo new
  • Build the project: cargo build
  • Run the project: cargo run
  • Update project dependencies: cargo update
  • Run tests: cargo test
  • Generate the project documentation via rustdoc: cargo doc
  • Analyze the project to see it has any errors, without building it: cargo check

In addition, there are cargo commands to publish the project as a crate/ package to Rust’s official crate registry, crates.io.

πŸ’‘ We need to get an API token from crates.io to publish a crate to it. The API token can be found in the Account Settings page, after login to that site. We will discuss more about this under code organization with crates.

  • Log in to crates.io with the API token: cargo login
  • Make the local crate uploadable to crates.io: cargo package
  • Upload the crate to crates.io: cargo publish

Crate

A crate is a package, which can be shared via crates.io. A crate can produce an executable or a library. In other words, it can be a binary crate or a library crate.

  1. cargo new crate_name --bin or cargo new crate_name: Produces an executable
  2. cargo new crate_name --lib: Produces a library

The first one generates,

β”œβ”€β”€ Cargo.toml
└── src
    └── main.rs

and the second one generates,

β”œβ”€β”€ Cargo.toml
└── src
    └── lib.rs
  • Cargo.toml(capital c) is the configuration file which contains all of the metadata that Cargo needs to compile your project.
  • src folder is the place to store the source code.
  • Each crate has an implicit crate root/ entry point. main.rs is the crate root for a binary crate and lib.rs is the crate root for a library crate.

πŸ’‘ When we build a binary crate via cargo build or cargo run, the executable file will be stored in target/debug/ folder. But when building it via cargo build --release for a release it will be stored in target/release/ folder.

Project Structure

This is how Cargo Docs describes about the recommended project layout,

.
β”œβ”€β”€ Cargo.lock
β”œβ”€β”€ Cargo.toml
β”œβ”€β”€ benches
β”‚   └── large-input.rs
β”œβ”€β”€ examples
β”‚   └── simple.rs
β”œβ”€β”€ src
β”‚   β”œβ”€β”€ bin
β”‚   β”‚   └── another_executable.rs
β”‚   β”œβ”€β”€ lib.rs
β”‚   └── main.rs
└── tests
    └── some-integration-tests.rs
  • The source code goes in the src directory.
  • The default library file is src/lib.rs.
  • The default executable file is src/main.rs.
  • Other executables can be placed in src/bin/*.rs.
  • Integration tests go in the tests directory (unit tests go in each file they’re testing).
  • Examples go in the examples directory.
  • Benchmarks go in the benches directory.