Skip to content

Module System

Updated
17 Sept 2026
4 min read
2 sections
Page 15 of 18
Rust
  • cargo new creates 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
toml
[package]
name = "my-project"
version = "0.1.0"
edition = "2021"
  • if src/main.rs is present, a binary crate with the same name as the package will be automatically created
  • src/main.rs will be the crate route (entry point of the binary crate)
  • src/lib.rs will automatically create a library crate with same name as the package

Rules:

  1. A package must have atleast one crate
  2. A package can have either zero or one library crate
  3. 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>

Out · output
$ cargo new --lib restaurant

Creating library `restaurant` package
Adding `restaurant` as member of workspace at /05-modules
rust
mod front_of_house {
    mod hosting {
        fn add_to_waitlist() {}
    }

    mod serving {
        fn take_order() {}

        fn serve_order() {}

        fn take_payment() {}
    }
}
  • mod keyword is used to define a module
  • Module is called Crate in Rust

Paths

  • Absolute Path: Starts from the crate root by using crate keyword
rust
crate::front_of_house::hosting::add_to_waitlist();
  • Relative Path: Starts from the current module
rust
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
rust
mod front_of_house {
    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();
}
  • pub{:rust} keyword is used to make the modules and functions public
rust
fn serve_order() {}

mod back_of_house {
    fn fix_incorrect_order() {
        cook_order();
        super::serve_order();
    }

    fn cook_order() {}
}
  • super{:rust} keyword is used to access the parent module

Privacy Rules in Structs

  • By default, structs are private
rust
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);
}
rust
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 pub keyword
rust
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

rust
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;
}
Out · error
Error: Appetizer is private
rust
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
rust
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();
}
  • use{:rust} keyword to bring the module into scope
rust
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();
}
rust
use std::fmt;
use std::io;

fn function1() -> fmt::Result {
    // --snip--
    Ok(())
}

fn function2() -> io::Result<()> {
    // --snip--
    Ok(())
}
Out · output
Warning: `Result` is ambiguous
  • as{:rust} keyword to rename the Result type
rust
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
rust
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 use{:rust} reexports the module
rust
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();
}
rust
use rand::CryptoRng;
use rand::ErrorKind::Transient;
use rand::Rng;

use std::io;
use std::io::Write;
  • We can use the use keyword to bring multiple items into scope
rust
use rand::{CryptoRng, ErrorKind::Transient, Rng};

use std::io::{self, Write};
  • glob operator * to bring all items into scope
rust
use std::collections::*;
rust
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();
}
rust
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();
}
  • use keyword to bring the module into scope
rust
pub mod hosting {
    pub fn add_to_waitlist() {}
}