As you write large programs, organizing your code will become increasingly important. By grouping related functionality and separating code with distinct features, you’ll clarify where to find code that implements a particular feature and where to go to change how a feature works.
Rust has a number of features that allow you to manage your code’s organization, including which details are exposed, which details are private, and what names are in each scope in your programs. These features, sometimes collectively referred to as the module system, include:
⇒ A crate is the smallest amount of code that the Rust compiler considers at a time.
main that defines what happens when the executable runs. All the crates we’ve created so far have been binary crates.main function, and they don’t compile into an executable. Instead, they define functionality intended to be shared with multiple projects. For example, the rand cratelibrary crate, and they use “crate” interchangeably with the general programming concept of a “library".*crate root* is a source file that the Rust compiler starts from and makes up the root module of your crate.⇒ A package is a bundle of one or more crates that provides a set of functionalities. A package contains a Cargo.toml file that describes how to build those crates.
After we run cargo new, we use ls to see what Cargo creates.
rustc to build the library or binary.<aside>
📌 A package can have multiple binary crates by placing files in the *src/bin* directory: each file will be a separate binary crate.
</aside>
<aside>
📌 Create a new library named restaurant by running cargo new restaurant --lib
</aside>
mod front_of_house {
mod hosting {
fn add_to_waitlist() {}
fn seat_at_table() {}
}
mod serving {
fn take_order() {}
fn serve_order() {}
fn take_payment() {}
}
}
Inside modules, we can place other modules, as in this case with the modules hosting and serving.
Modules can also hold definitions for other items, such as structs, enums, constants, traits, and functions.
we mentioned that src/main.rs and src/lib.rs are called crate roots. The reason for their name is that the contents of either of these two files form a module named crate at the root of the crate’s module structure, known as the module tree.
Listing 7-2 shows the module tree for the structure in Listing 7-1.
crate
└── front_of_house
├── hosting
│ ├── add_to_waitlist
│ └── seat_at_table
└── serving
├── take_order
├── serve_order
└── take_payment
Notice that the entire module tree is rooted under the implicit module named crate.
paths that allow you to name items;
the use keyword that brings a path into scope;
and the pub keyword to make items public.
• Start from the crate root: When compiling a crate, the compiler first looks in the crate root file (usually src/lib.rs for a library crate or src/main.rs for a binary crate) for code to compile.
mod garden;. The compiler will look for the module’s code in these places:
mod gardenmod vegetables; in src/garden.rs. The compiler will look for the submodule’s code within the directory named for the parent module in these places:
mod vegetables, within curly brackets instead of the semicolonAsparagus type in the garden vegetables module would be found at crate::garden::vegetables::Asparagus.pub mod instead of mod. To make items within a public module public as well, use pub before their declarations.use keyword: Within a scope, the use keyword creates shortcuts to items to reduce the repetition of long paths. In any scope that can refer to crate::garden::vegetables::Asparagus, you can create a shortcut with use crate::garden::vegetables::Asparagus; and from then on you only need to write Asparagus to make use of that type in the scope.Here we create a binary crate named backyard that illustrates these rules. The crate’s directory, also named backyard, contains these files and directories:
backyard
├── Cargo.lock
├── Cargo.toml
└── src
├── garden
│ └── vegetables.rs
├── garden.rs
└── main.rs
The crate root file in this case is src/main.rs, and it contains:
Filename: src/main.rs
use crate::garden::vegetables::Asparagus;
pub mod garden;
fn main() {
let plant = Asparagus {};
println!("I'm growing {:?}!", plant);
}
The pub mod garden; line tells the compiler to include the code it finds in src/garden.rs, which is:
Filename: src/garden.rs
pub mod vegetables;
Here, pub mod vegetables; means the code in src/garden/vegetables.rs is included too. That code is:
#[derive(Debug)]
pub struct Asparagus {}
⇒ path: To show Rust where to find an item in a module tree.
A path can take two forms:
crate.self, super, or an identifier in the current module.separated by double colons (::).