Defining Modules to Control Scope and Privacy

Module System Quick Reference

  • Crate root: Compiler starts at src/lib.rs (library) or src/main.rs (binary)
  • Module declaration: mod garden; looks for code in:
    • Inline: mod garden { ... }
    • File: src/garden.rs
    • Directory: src/garden/mod.rs
  • Submodules: Declared in parent module files, found in subdirectories
  • Paths: Access items via crate::module::item (absolute) or module::item (relative)
  • Privacy: Items are private by default; use pub to expose them
  • use keyword: Creates shortcuts to reduce path repetition

Example Structure

backyard
├── Cargo.toml
└── src
    ├── garden
    │   └── vegetables.rs
    ├── garden.rs
    └── main.rs
use crate::garden::vegetables::Asparagus;

pub mod garden;

fn main() {
    let plant = Asparagus {};
    println!("I'm growing {plant:?}!");
}
pub mod vegetables;
#[derive(Debug)]
pub struct Asparagus {}

Organizing Code with Modules

Modules provide namespace organization and privacy control. Unlike JavaScript imports which expose everything explicitly exported, Rust items are private by default.

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() {}
    }
}

This creates a module tree:

crate
 └── front_of_house
     ├── hosting
     │   ├── add_to_waitlist
     │   └── seat_at_table
     └── serving
         ├── take_order
         ├── serve_order
         └── take_payment

The crate root forms an implicit crate module. Child modules can access parent items, but parents cannot access private child items without explicit pub declarations.