RustArena

Step 1 of 7

Modules and privacy

As a program grows, you need a way to group related code and to hide the details. A module is a named container for functions, structs, enums, constants and other modules. You create one with mod:

mod arena {
    pub fn welcome(name: &str) {
        println!("Welcome to the arena, {name}!");
        open_gates();
    }

    fn open_gates() {
        println!("(the gates creak open)");
    }
}

fn main() {
    arena::welcome("Ferris");
}
Welcome to the arena, Ferris!
(the gates creak open)

Piece by piece:

Why private by default? A module's public items are its interface: what others may rely on. Private items are details you can change or delete later without breaking anyone. At work this matters a lot: if a helper isn't pub, you know nobody outside depends on it.

Calling a private function

mod arena {
    pub fn welcome() {
        println!("Welcome!");
    }

    fn secret_door() {
        println!("You found the secret door");
    }
}

fn main() {
    arena::welcome();
    arena::secret_door();
}
error[E0603]: function `secret_door` is private

The full message points at the definition (note: the function `secret_door` is defined here), so you can decide whether it should be pub or whether you're reaching for something you shouldn't.

Modules inside modules

Modules nest, and every module on a path must be reachable:

mod garden {
    pub mod vegetables {
        pub fn harvest() -> u32 {
            12
        }
    }

    pub fn report() {
        println!("harvested {} carrots", vegetables::harvest());
    }
}

fn main() {
    garden::report();
    println!("{}", garden::vegetables::harvest());
}
harvested 12 carrots
12

The privacy rule in one sentence: a private item is visible in its own module and in all the modules inside it; pub also makes it visible wherever its parent module is visible. So a child can use its parent's private items, but a parent can't use its child's private items.

Common mistakes

Your task

Fill in the blanks: declare the module scoreboard, and make record public so main can call it. The program prints Ferris: 120 pts.

Challenge 2

Move the two conversion functions into a module named temperature, and make them public, so that temperature::c_to_f and temperature::f_to_c work. The hidden tests call them through the module path.

Challenge 3

Build this module structure from scratch:

The tests call shop::pricing::with_tax and shop::receipt.

Next: Paths: crate, super and self