Module System
-
cargo newcreates a new package -
A package can contain multiple binary crates and one library crate
-
Crates are two types:
- Binary: Code that can be executed
- Library: Code that can be used by other crates
-
Crates contain modules
-
Modules allows organizing code with privacy rules
[package]
name = "my-project"
version = "0.1.0"
edition = "2021"-
if
src/main.rsis present, a binary crate with the same name as the package will be automatically created -
src/main.rswill be the crate route (entry point of the binary crate) -
src/lib.rswill automatically create a library crate with same name as the package
Rules:
- A package must have atleast one crate
- A package can have either zero or one library crate
- A package can have multiple binary crates
If we want more than one binary crate, we can create a new binary crate using cargo new --bin <name>
$ cargo new --lib restaurant
Creating library `restaurant` package
Adding `restaurant` as member of workspace at `C:\Code\Learning\Learning-Rust\05-modules`- lib.rs
- Cargo.lock
- Cargo.toml
- Cargo.lock
- Cargo.toml
restaurant/src/lib.rs
mod front_of_house {
mod hosting {
fn add_to_waitlist() {}
fn add_to_waitlist() {}
}
mod serving {
fn take_order() {}
fn serve_order() {}
fn take_payment() {}
}
}
modkeyword is used to define a module- Module is called Crate in Rust
Paths
- Absolute Path: Starts from the crate root by using
cratekeyword
crate::front_of_house::hosting::add_to_waitlist();- Relative Path: Starts from the current module
self::front_of_house::hosting::add_to_waitlist();- By default, a child module and everything inside it is private from the perspective of the parent module
mod front_of_hosue {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub fn eat_at_restaurant() {
// Absolute path
crate::front_of_house::hosting::add_to_waitlist();
// Relative path
front_of_house::hosting::add_to_waitlist();
}pubkeyword is used to make the modules and functions public
fn serve_order() {}
mod back_of_house {
fn fix_incorrect_order() {
cook_order();
super::serve_order();
}
fn cook_order() {}
}
superkeyword is used to access the parent module
Privacy Rules in Structs
- By default, structs are private
mod back_of_house {
pub struct Breakfast {
toast: String,
seasonal_fruit: String,
}
impl Breakfast {
pub fn summer(toast: &str) -> Breakfast {
Breakfast {
toast: String::from(toast),
seasonal_fruit: String::from("peaches"),
}
}
}
}
pub fn eat_at_restaurant() {
// Order a breakfast in the summer with Rye toast
let mut meal = back_of_house::Breakfast::summer("Rye");
// Change our mind about what bread we'd like
meal.toast = String::from("Wheat");
println!("I'd like {} toast please", meal.toast);
}
mod back_of_house {
pub struct Breakfast {
pub toast: String,
seasonal_fruit: String,
}
impl Breakfast {
pub fn summer(toast: &str) -> Breakfast {
Breakfast {
toast: String::from(toast),
seasonal_fruit: String::from("peaches"),
}
}
}
}
pub fn eat_at_restaurant() {
// Order a breakfast in the summer with Rye toast
let mut meal = back_of_house::Breakfast::summer("Rye");
// Change our mind about what bread we'd like
meal.toast = String::from("Wheat");
println!("I'd like {} toast please", meal.toast);
}- We can make the fields of the struct public by using
pubkeyword
mod back_of_house {
pub struct Breakfast {
pub toast: String,
pub seasonal_fruit: String,
}
impl Breakfast {
pub fn summer(toast: &str) -> Breakfast {
Breakfast {
toast: String::from(toast),
seasonal_fruit: String::from("peaches"),
}
}
}
}
pub fn eat_at_restaurant() {
let mut meal = back_of_house::Breakfast {
toast: String::from("Rye"),
seasonal_fruit: String::from("peaches"),
};
// Change our mind about what bread we'd like
meal.toast = String::from("Wheat");
println!("I'd like {} toast please", meal.toast);
}Enums
mod back_of_house {
enum Appetizer {
Soup,
Salad,
}
}
pub fn eat_at_restaurant() {
// Order a soup
let order1 = back_of_house::Appetizer::Soup;
// Order a salad
let order2 = back_of_house::Appetizer::Salad;
}️⛔
Error: Appetizer is private
mod back_of_house {
pub enum Appetizer {
Soup,
Salad,
}
}
pub fn eat_at_restaurant() {
// Order a soup
let order1 = back_of_house::Appetizer::Soup;
// Order a salad
let order2 = back_of_house::Appetizer::Salad;
}- Enums are private by default
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub fn eat_at_restaurant() {
front_of_house::hosting::add_to_waitlist();
front_of_house::hosting::add_to_waitlist();
front_of_house::hosting::add_to_waitlist();
}usekeyword to bring the module into scope
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
use self::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}use std::fmt;
use std::io;
fn function1() -> fmt::Result {
// --snip--
Ok(())
}
fn function2() -> io::Result<()> {
// --snip--
Ok(())
}️⚠️
Warning: Result is ambiguous
askeyword to rename theResulttype
use std::fmt::Result;
use std::io::Result as IoResult;
fn function1() -> Result {
// --snip--
Ok(())
}
fn function2() -> IoResult<()> {
// --snip--
Ok(())
}- External code cannot use the internal modules
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
use self::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}-
If we want external code to use our library, we need to make the library public, and reexport the hosting module
-
pub usereexports the module
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub use self::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}use rand::CryptoRng;
use rand::ErrorKind::Transient;
use rand::Rng;
use std::io;
use std::io::Write;- We can use the
usekeyword to bring multiple items into scope
use rand::{CryptoRng, ErrorKind::Transient, Rng};
use std::io::{self, Write};- glob operator
*to bring all items into scope
use std::collections::*;mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub use self::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}mod front_of_house;
pub use self::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}usekeyword to bring the module into scope
front_of_house.rs
pub mod hosting {
pub fn add_to_waitlist() {}
}