In the Rust programming language, the module system is a key feature that helps manage and organize code, especially in large-scale projects. The first parts of this system that we'll cover are packages and crates.
Crate
A crate is the smallest unit of code that the Rust compiler considers at a time. This can be a single source code file passed to `rustc` rather than `cargo`. Crates can contain modules, which may be defined in other files that get compiled with the crate.
Crates can come in two forms: a binary crate or a library crate.
- Binary Crates: These are programs that you can compile into an executable that you can run, such as a command-line program or a server. Each binary crate must have a function called `main` that defines what happens when the executable runs.
- Library Crates: These don't have a `main` function and don't compile to an executable. Instead, they define functionality intended to be shared with multiple projects. For example, the `rand` crate provides functionality that generates random numbers.
The crate root is a source file that the Rust compiler starts from and makes up the root module of your crate.
Packages
A package is a bundle of one or more crates that provides a set of functionality. A package contains a `Cargo.toml` file that describes how to build those crates.
A package can contain as many binary crates as you like, but at most only one library crate. A package must contain at least one crate, whether that’s a library or binary crate.
When we create a package using the command `cargo new`, Cargo creates a project directory with a `Cargo.toml` file (giving us a package) and a `src` directory that contains `main.rs`. Cargo follows a convention that `src/main.rs` is the crate root of a binary crate with the same name as the package. Likewise, if the package directory contains `src/lib.rs`, the package contains a library crate with the same name as the package, and `src/lib.rs` is its crate root.