0% found this document useful (0 votes)
17 views17 pages

Rust Chapter7 Modules - HTML

Chapter 7 of 'The Rust Programming Language' discusses the use of modules for organizing code, controlling visibility, and managing namespaces. It introduces key concepts such as the 'mod', 'pub', and 'use' keywords, along with rules for file organization and privacy. The chapter emphasizes the importance of structuring code effectively as projects grow, using real-world analogies to illustrate these concepts.

Uploaded by

lollyvenicel
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views17 pages

Rust Chapter7 Modules - HTML

Chapter 7 of 'The Rust Programming Language' discusses the use of modules for organizing code, controlling visibility, and managing namespaces. It introduces key concepts such as the 'mod', 'pub', and 'use' keywords, along with rules for file organization and privacy. The chapter emphasizes the importance of structuring code effectively as projects grow, using real-world analogies to illustrate these concepts.

Uploaded by

lollyvenicel
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

CHAPTER 7

Modules & Code


Organization CHAPTER 7 · THE RUST PROGRAMMING LANGUAGE

FOUNDATIONS
Using
Modules to
01 The Big Picture

02 mod keyword

03

04
Modules to Files

Submodule Rule
Reuse
VISIBILITY
and Organize
Code
05 pub keyword

06 Privacy Rules

07 Privacy Examples Learn how Rust's module system lets you split code into namespaced units,
PATHS & SCOPE control what's public or private, and bring names into scope cleanly. Three
08 use keyword keywords rule them all.

09 Glob & Multi-use


mod pub use super
10 super keyword
MASTERY

11 Full Walkthrough

12 Practice Problems
01 — BIG PICTURE
13 Cheatsheet
Why Do We Need Modules?
As programs grow, putting everything in [Link] becomes unmanageable. You need a way to group
related code, hide implementation details, and expose a clean API. That's exactly what modules do.

📦 REAL-WORLD ANALOGY

Think of a large company. You don't expose every internal process to every employee — HR
handles hiring, Engineering handles code, Finance handles money. Each department has a
public interface (what they'll do for you) and private internals (how they do it). Modules work
the same way in Rust.

Modules give you three things:

Namespacing — two modules can each have a function named connect() without conflict
Privacy — hide implementation details; only expose what users need
Organization — split code across files as the project scales

The Three Keywords — One-Line Summary Each

MODULE SYSTEM OVERVIEW

mod → declares a module (creates a namespace)


pub → makes something visible outside its module (opt-in public)
use → brings a name into local scope (shorter path)
super → navigates up one level in the module tree
Default: everything is PRIVATE. You must explicitly opt-in to public.
CHAPTER 7

Modules & Code


Organization

02 — MOD KEYWORD

FOUNDATIONS Defining Modules with mod


01 The Big Picture
You declare a module using the mod keyword followed by a name and curly braces. Everything inside
02 mod keyword lives in that namespace:
03 Modules to Files
SRC/[Link]
04 Submodule Rule
VISIBILITY mod network {
fn connect() {
05 pub keyword
// code here
06 Privacy Rules }
}
07 Privacy Examples
PATHS & SCOPE

To call connect from outside the network module, you use :: path syntax:
08 use keyword

09 Glob & Multi-use RUST

10 super keyword
network::connect(); // must use full path from outside the module
MASTERY

11 Full Walkthrough

12 Practice Problems Side-by-Side Modules

13 Cheatsheet You can have as many sibling modules as you need. They each form their own namespace so function
names don't clash:

SRC/[Link] — SIBLING MODULES

mod network {
fn connect() {} // ← network::connect()
}

mod client {
fn connect() {} // ← client::connect() — totally different!
}

✅ KEY POINT

The same function name in different modules causes zero conflict. Each module is its own
namespace. This is exactly why namespacing matters.

Nested Modules

You can put modules inside modules. The path just gets longer:

SRC/[Link] — NESTED MODULES

mod network {
fn connect() {} // path: network::connect()

mod server {
fn connect() {} // path: network::server::connect()
}

mod client {
fn connect() {} // path: network::client::connect()
CHAPTER 7 }
Modules & Code }
Organization

Visualizing the Hierarchy


FOUNDATIONS

01 The Big Picture


MODULE TREE
02 mod keyword

03 Modules to Files communicator (crate root = src/[Link])


├── network
04 Submodule Rule │ ├── server
VISIBILITY │ └── client
└── client (top-level, sibling of network)
05 pub keyword
Each node is its own namespace. Paths go from top down with ::
06 Privacy Rules

07 Privacy Examples
PATHS & SCOPE

08 use keyword 03 — MOVING MODULES TO FILES

09 Glob & Multi-use Splitting Modules Across Files


10 super keyword When a module grows large, you move it to its own file. The trick: replace the module body with a
MASTERY semicolon. This tells Rust "look for this module's content in a separate file".
11 Full Walkthrough

12 Practice Problems
🧠 THE KEY MENTAL MODEL

mod client;(with semicolon) means: "There IS a module named client, but its contents are in
13 Cheatsheet
another file — go find src/[Link] ."

mod client { ... } (with body) means: "Here is the module, right here, inline."

❌ Before — inline (gets huge) ✅ After — split into files

// src/[Link] // src/[Link]
mod client { mod client; // ← semicolon! body in [Link]
fn connect() {} mod network; // ← semicolon! body in [Link]
fn disconnect() {}
// 500 more lines...
}
mod network {
// 800 more lines...
}

Step-by-Step: Extracting a Module to a File

1 In src/[Link] — replace the module body with a semicolon

mod client; // was: mod client { fn connect() {} }

2 Create src/[Link] — put the body here

SRC/[Link]
CHAPTER 7 // DO NOT write "mod client" here!

Modules & Code // Just write the contents directly.


Organization fn connect() {}

FOUNDATIONS
3 Run cargo build — it should compile
01 The Big Picture Rust automatically finds src/[Link] when it sees mod client; in src/[Link] .
02 mod keyword

Modules to Files
03
🚨 THE #1 MISTAKE — DON'T DO THIS

04 Submodule Rule
SRC/[Link] — WRONG!
VISIBILITY

05 pub keyword mod client { // ❌ This creates client::client — a nested module!


fn connect() {}
06 Privacy Rules
}
07 Privacy Examples
PATHS & SCOPE
You already declared mod client in src/[Link] . The file IS the module. Don't declare it again
08 use keyword inside itself.
09 Glob & Multi-use

10 super keyword
MASTERY
04 — THE SUBMODULE DIRECTORY RULE
11 Full Walkthrough
When a Module Has Submodules: Use a
12 Practice Problems
Directory
13 Cheatsheet
Here's where most beginners get confused. When you want to split a module that itself has child
modules, you can't just use a .rs file — you need a directory with a [Link] inside it.

⚠️ THE PROBLEM

If network is in src/[Link] and you write mod server; inside it, Rust will error: "cannot
declare a new module at this location." Rust can't tell that src/[Link] belongs to network
— it looks like a top-level module!

The Two File Rules

FILE SYSTEM RULES — MEMORIZE THESE

Rule 1: Module foo with NO submodules → file src/[Link]

Rule 2: Module foo WITH submodules → file src/foo/[Link]

These rules apply recursively down the tree.

The Solution: Convert to Directory

1 Create a directory named after the parent module

TERMINAL

mkdir src/network

2 Move src/[Link] → src/network/[Link]


TERMINAL
CHAPTER 7

Modules & Code


mv src/[Link] src/network/[Link]
Organization

FOUNDATIONS 3 Move the submodule file into the directory


01 The Big Picture
TERMINAL
02 mod keyword

03 Modules to Files mv src/[Link] src/network/[Link]

04 Submodule Rule
VISIBILITY
4 In src/network/[Link] — declare the submodule
05 pub keyword
SRC/NETWORK/[Link]
06 Privacy Rules

07 Privacy Examples fn connect() {}


PATHS & SCOPE
mod server; // tells Rust: look in src/network/[Link]
08 use keyword

09 Glob & Multi-use

10 super keyword
The Complete File Layout
MASTERY

11 Full Walkthrough
FILE TREE ↔ MODULE TREE
12 Practice Problems

13 Cheatsheet
📁 FILE TREE 🌳 MODULE TREE
src/ communicator
├── [Link] ├── client
├── [Link] └── network
└── network/ └── server
├── [Link]
└── [Link]

The module hierarchy stays IDENTICAL. Only the file layout changes.

💡 WHY THIS RULE EXISTS

Rust needs to know which module is the parent of a file. When [Link] is inside the
network/ directory, Rust knows it belongs to network . If it were at src/[Link] , Rust would
think it's a sibling of network , not a child. The directory structure encodes the parent-child
relationship.

05 — PUB KEYWORD

Controlling Visibility with pub


Everything in Rust is private by default. That means functions, structs, modules — all of it. Only code
within the same module (or its children) can access private items. The pub keyword opts an item into
public visibility.

🔒 PRIVACY ANALOGY
Imagine a house. The front door (public API) is accessible to guests. The bedrooms and
CHAPTER 7 basement (private internals) are not. You explicitly choose what's guest-accessible. Rust does
Modules & Code the same — everything starts locked; you unlock only what you need.
Organization

FOUNDATIONS
The Cascading pub Problem
01 The Big Picture
This is the most common mistake: you make a function pub but forget to make its parent module pub .
02 mod keyword
Both must be public for outside code to reach the function.
03 Modules to Files

04 Submodule Rule STEP 1 — MISSING PUB ON MODULE

VISIBILITY
SRC/[Link]
05 pub keyword

06 Privacy Rules mod client; // ← private module!


mod network;
07 Privacy Examples
PATHS & SCOPE
Error: "module 'client' is private"
08 use keyword

09 Glob & Multi-use ↓


10 super keyword
STEP 2 — MODULE IS PUBLIC BUT FUNCTION IS NOT
MASTERY

SRC/[Link]
11 Full Walkthrough

12 Practice Problems pub mod client; // ✅ module is public now

13 Cheatsheet mod network;

SRC/[Link]

fn connect() {} // ← still private!

Error: "function 'connect' is private"


STEP 3 — BOTH MODULE AND FUNCTION ARE PUBLIC ✅
SRC/[Link]

pub mod client; // ✅ public module


pub mod network; // ✅ public module

SRC/[Link]

pub fn connect() {} // ✅ public function

✅ Works! Outside code can call communicator::client::connect()

What Can Be Made Public?

pub mod — public module


pub fn — public function
pub struct — public struct (but fields are still private by default!)
pub field — public struct field (must do per-field)
CHAPTER 7
pub enum — public enum (all variants are public automatically)
Modules & Code
Organization pub const / pub static — public constants

FOUNDATIONS
06 — PRIVACY RULES

01 The Big Picture


The Two Privacy Rules
02 mod keyword
Rust's privacy system is governed by exactly two rules. If you memorize these, you can reason about
03 Modules to Files
any visibility question:
04 Submodule Rule
VISIBILITY
THE TWO RULES

05 pub keyword
Rule 1 — Public item:
06 Privacy Rules
Can be accessed through any of its parent modules.
07 Privacy Examples
Rule 2 — Private item:
PATHS & SCOPE
Can ONLY be accessed by its own module and any of that module's child modules.
08 use keyword
Parents can see public children. Parents CANNOT see private children's internals.
09 Glob & Multi-use Children can always see their parents.
10 super keyword
MASTERY

Visibility Reference Table


11 Full Walkthrough

12 Practice Problems Who wants access? Private item Public item

13 Cheatsheet
Same module ✅ YES ✅ YES
Child module (nested inside) ✅ YES ✅ YES
Parent module ❌ NO ✅ YES
Sibling module ❌ NO ✅ YES (via parent)
External crate ❌ NO ✅ YES (via pub chain)

07 — PRIVACY IN PRACTICE

Working Through Privacy Examples


The book gives a great example that tests your understanding. Let's work through it slowly, line by line.

SRC/[Link] — THE EXAMPLE

mod outermost {
pub fn middle_function() {} // pub
fn middle_secret_function() {} // private

mod inside { // private module


pub fn inner_function() {} // pub, but module is private!
fn secret_function() {} // private
}
}

fn try_me() {
outermost::middle_function(); // ?
outermost::middle_secret_function(); // ?
outermost::inside::inner_function(); // ?
outermost::inside::secret_function(); // ?
CHAPTER 7 }
Modules & Code
Organization
Before reading the answers — which lines compile? Think through each one using the two rules.

FOUNDATIONS
Line-by-Line Analysis
01 The Big Picture

02 mod keyword

03 Modules to Files ✅ WORKS


04 Submodule Rule
outermost::middle_function();
VISIBILITY

05 pub keyword
Why? try_me is in the root module. outermost is private, but Rule 2 says: a private item can
06 Privacy Rules be accessed by its parent module. The root module IS the parent of outermost . And
07 Privacy Examples
middle_function is pub . Both checks pass. ✅
PATHS & SCOPE

08 use keyword

09 Glob & Multi-use


❌ ERROR
10 super keyword
MASTERY outermost::middle_secret_function();

11 Full Walkthrough

Practice Problems Why? middle_secret_function is private. The root module is not its own module, nor a child of

12

its module ( outermost ). Rule 2 fails — access denied.


13 Cheatsheet

❌ ERROR
outermost::inside::inner_function();

Why? Even though inner_function is pub , the inside module itself is private. You can't
reach through a private module to get to a public item inside it. The inside module is only
accessible by outermost and outermost 's children — not by the root. ❌

❌ ERROR
outermost::inside::secret_function();

Why? Double fail: inside is private AND secret_function is private. ❌

✅ HOW TO FIX THE ERRORS

To make outermost::inside::inner_function() work from the root, you'd need to make both
outermost and inside public: pub mod outermost { pub mod inside { pub fn
inner_function() {} } } . Every link in the chain must be public.
CHAPTER 7

Modules & Code


08 — USE KEYWORD
Organization

Bringing Names into Scope with use


FOUNDATIONS Typing full module paths every time gets tedious. use brings a name into local scope so you can use it
01 The Big Picture with a shorter reference:

02 mod keyword

03 Modules to Files
❌ Without use — verbose ✅ With use — clean

04 Submodule Rule
fn main() { use a::series::of;
VISIBILITY
a::series::of::nested_modules();
05 pub keyword a::series::of::nested_modules(); fn main() {
a::series::of::nested_modules(); of::nested_modules();
06 Privacy Rules } of::nested_modules();
07 Privacy Examples of::nested_modules();
}
PATHS & SCOPE

08 use keyword

09 Glob & Multi-use

10 super keyword Three Levels of use Specificity


MASTERY

RUST — LEVELS OF USE


11 Full Walkthrough

12 Practice Problems // Level 1: bring the module in — still need module::function()


use a::series::of;
13 Cheatsheet
of::nested_modules();

// Level 2: bring the function in directly — call it bare


use a::series::of::nested_modules;
nested_modules();

// Level 3: for enums, bring variants in directly


use TrafficLight::{Red, Yellow};
let r = Red; // no TrafficLight:: prefix needed
let y = Yellow; // no TrafficLight:: prefix needed

🧠 IDIOMATIC RUST CONVENTION

For functions, the convention is to use the parent module, not the function itself. This makes it
clear the function isn't local: you write module::function() . For types (structs, enums), it's
idiomatic to bring them in directly: use std::collections::HashMap then use HashMap bare.

use in Scope Rules

use only applies to the scope it's in. If you write use at the top level of a file, it's available throughout
that file. If you write it inside a function, it's only available in that function.

RUST — USE SCOPE

use a::series::of; // available throughout this file/scope

fn foo() {
of::nested_modules(); // ✅ works
}

fn bar() {
of::nested_modules(); // ✅ also works
CHAPTER 7 }
Modules & Code
Organization

09 — GLOB & MULTIPLE ITEMS


FOUNDATIONS

Importing Multiple Items & Glob Imports


01 The Big Picture

02 mod keyword
Bringing Multiple Items from One Namespace
03 Modules to Files
Use curly braces to import multiple items from the same path in one use statement:
04 Submodule Rule
VISIBILITY RUST — MULTIPLE USE

05 pub keyword
enum TrafficLight { Red, Yellow, Green }
06 Privacy Rules
// Import two variants explicitly
07 Privacy Examples
use TrafficLight::{Red, Yellow};
PATHS & SCOPE

use keyword fn main() {


08
let red = Red; // ✅ no prefix needed
09 Glob & Multi-use let yellow = Yellow; // ✅
no prefix needed
let green = TrafficLight::Green; // needs prefix — not imported
10 super keyword
}
MASTERY

11 Full Walkthrough

12 Practice Problems The Glob Operator *

13 Cheatsheet The glob operator imports everything visible from a namespace at once:

RUST — GLOB

use TrafficLight::*; // bring in ALL variants

fn main() {
let r = Red; // ✅
let y = Yellow; // ✅
let g = Green; // ✅ all imported
}

⚠️ USE GLOBS SPARINGLY

Glob imports are convenient but dangerous. They can pull in names you didn't expect, causing
naming conflicts that are hard to debug. You also lose visibility into where a name came from.
Use explicit imports in production code. Globs are acceptable in tests and preludes.

Standard Library Uses

In real Rust code, you'll use use constantly for standard library types:

RUST — REAL-WORLD USE EXAMPLES

use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::{HashMap, HashSet}; // both at once
use std::io::Result;
use std::fmt;
CHAPTER 7

Modules & Code


10 — SUPER KEYWORD
Organization

Navigating Up the Tree with super


FOUNDATIONS Inside a module, paths are relative to your current location. If you're in a child module and need to
01 The Big Picture reference something in the parent, you use super — it means "go up one level."

02 mod keyword
PATH NAVIGATION
03 Modules to Files

04 Submodule Rule communicator (root)


├── client
VISIBILITY
└── tests ← you are here
05 pub keyword
From tests, to reach client:
06 Privacy Rules
Option 1: ::client::connect() — absolute from root
07 Privacy Examples Option 2: super::client::connect() — go up one level, then navigate
PATHS & SCOPE

08 use keyword

09 Glob & Multi-use The Problem: Why You Need super

10 super keyword
THIS FAILS — PATHS ARE RELATIVE TO CURRENT MODULE
MASTERY

11 Full Walkthrough #[cfg(test)]


mod tests {
12 Practice Problems #[test]
fn it_works() {
13 Cheatsheet
client::connect(); // ❌ ERROR: `client` not found
// Rust looks for `tests::client` — doesn't exist!
}
}

Solution: Use super or Absolute Path

Option A — Absolute path Option B — super (preferred)

::client::connect(); super::client::connect();
// Start from crate root, go down // Go up one level, then navigate

Best Practice: use super in Tests

The idiomatic pattern is to combine super with use so you don't have to write super:: in front of
every single call:

✅ IDIOMATIC PATTERN FOR TEST MODULES

#[cfg(test)]
mod tests {
use super::client; // bring client into scope once

#[test]
fn test_connect() {
client::connect(); // ✅ clean, no super:: every time
}
#[test]
CHAPTER 7 fn test_disconnect() {
Modules & Code client::disconnect(); // ✅ same import works for all tests
Organization }
}

FOUNDATIONS

01 The Big Picture ✅ WHY SUPER OVER ABSOLUTE PATH

02 mod keyword
If you use absolute paths like ::client::connect() everywhere and then refactor your module
tree — moving modules around — you'd need to update every absolute path. With super:: , as
03 Modules to Files long as the relative relationship stays the same, paths continue to work. Less brittle.
04 Submodule Rule
VISIBILITY

05 pub keyword
11 — COMPLETE WALKTHROUGH
06 Privacy Rules
Building the Communicator Library End-to-End
07 Privacy Examples
PATHS & SCOPE Let's put every concept together and build the complete communicator library from the book, step by
08 use keyword step, with every file shown.

09 Glob & Multi-use


The Goal
10 super keyword
MASTERY
We want this module tree:

11 Full Walkthrough
communicator
12 Practice Problems
├── client (public)
13 Cheatsheet └── network (public)
└── server (public)

File Layout

src/
├── [Link] ← crate root, declares modules
├── [Link] ← client module body
├── [Link] ← binary crate (uses the library)
└── network/
├── [Link] ← network module body, declares server submodule
└── [Link] ← network::server module body

Every File — Complete Code

SRC/[Link] — THE CRATE ROOT

pub mod client; // body in src/[Link]


pub mod network; // body in src/network/[Link]

#[cfg(test)]
mod tests {
use super::client;

#[test]
fn it_works() {
client::connect();
}
}
SRC/[Link] — CLIENT MODULE
CHAPTER 7

Modules & Code


pub fn connect() {
Organization
println!("client connected");
}

FOUNDATIONS

01 The Big Picture SRC/NETWORK/[Link] — NETWORK MODULE (HAS SUBMODULE)

02 mod keyword
pub fn connect() {
03 Modules to Files println!("network connected");
}
04 Submodule Rule
VISIBILITY pub mod server; // body in src/network/[Link]

05 pub keyword

06 Privacy Rules SRC/NETWORK/[Link] — NETWORK::SERVER MODULE

07 Privacy Examples
pub fn connect() {
PATHS & SCOPE println!("server connected");
}
08 use keyword

09 Glob & Multi-use


SRC/[Link] — BINARY CRATE THAT USES THE LIBRARY
10 super keyword
MASTERY
extern crate communicator; // bring in the library (older Rust editions)

11 Full Walkthrough // In Rust 2018+, this line is not needed

12 Practice Problems fn main() {


13 Cheatsheet communicator::client::connect();
communicator::network::connect();
communicator::network::server::connect();
}

Running It

TERMINAL

$ cargo build # compile the library


$ cargo test # run the tests
$ cargo run # run src/[Link]

💡 2015 VS 2018 EDITION NOTE

In Rust 2015 (this book's edition), you need extern crate mylib; in [Link] to use an external
crate. In Rust 2018+ (what you'll likely use), this line is no longer needed — Cargo handles it
automatically. Everything else in this chapter applies to both editions.

🧪 Practice Problems — Chapter 7


These problems build progressively. Each one adds a layer. Do them in order in the Rust
Playground or a local project.

PROBLEM 01 — Basic mod & Calling

Namespaces and Paths


In src/[Link], define two modules inline: math and text . In math , add a function
CHAPTER 7 double(n: i32) -> i32 . In text , add a function shout(s: &str) -> String that
Modules & Code returns the input uppercased. In main() , call both using full path syntax:
Organization
math::double(5) and text::shout("hello") .

💡 Hint: s.to_uppercase() returns a String. Call functions with


FOUNDATIONS module_name::function_name().

01 The Big Picture

02 mod keyword
PROBLEM 02 — pub & Privacy
03 Modules to Files
Controlling What's Visible
04 Submodule Rule
Create a module bank with a private function validate_pin(pin: u32) -> bool and a
VISIBILITY
public function withdraw(amount: f64, pin: u32) -> Result<f64, &'static str> . The
05 pub keyword public function calls the private one. In main() , call bank::withdraw(100.0, 1234) .
06 Privacy Rules Then try to call bank::validate_pin(1234) and observe the compile error.

07 Privacy Examples 💡 Hint: Private functions are accessible within the same module. Return Ok(amount) if pin is
PATHS & SCOPE
valid, Err("wrong pin") otherwise.

08 use keyword 🏆 Bonus: Make the module's public API only include withdraw and deposit . All validation logic stays
private.
09 Glob & Multi-use

10 super keyword
MASTERY PROBLEM 03 — Nested Modules

11 Full Walkthrough Building a Hierarchy

12 Practice Problems Define a module with two submodules: two_d and three_d . In two_d , add
shapes
pub fn circle_area(r: f64) -> f64 . In three_d , add pub fn sphere_volume(r: f64)
13 Cheatsheet
-> f64 . Make both submodules public. Call both functions from main() using full
paths: shapes::two_d::circle_area(3.0) and shapes::three_d::sphere_volume(3.0) .

💡 Hint: Circle area = π × r². Sphere volume = (4/3) × π × r³. Use std::f64::consts::PI.

PROBLEM 04 — use Keyword

Cleaning Up Paths

Take the code from Problem 03. Add use shapes::two_d and use shapes::three_d at
the top of main() . Rewrite the calls to use the shortened paths. Then add a third
function call using use shapes::two_d::circle_area so you can call it bare:
circle_area(5.0) .

💡 Hint: use only brings exactly what you specify into scope. Children of the module are not
automatically included.

PROBLEM 05 — File Modules (No Submodules)

Splitting into Files

Create a library project with cargo new mylib --lib . Split it into two files:
src/[Link] and src/[Link] . In [Link] , add pub fn hello(name: &str) ->
String . In [Link] , add pub fn goodbye(name: &str) -> String . In src/[Link] ,
declare both modules with mod greet; and mod farewell; and make them public.
Write a test in [Link] that calls both functions using use super::greet and use
super::farewell .

💡 Hint: Tests live in a mod tests block inside [Link]. Use use super::greet; to bring the
module into test scope. Run with cargo test.
CHAPTER 7 PROBLEM 06 — File Modules (With Submodules)

Modules & Code The Directory Pattern


Organization
Extend Problem 05. Add a greet submodule called formal . Create
src/greet/[Link] (move your [Link] content there), and create

FOUNDATIONS src/greet/[Link] with a pub fn formal_hello(name: &str) -> String that returns
"Good day, [name], I presume?" In src/greet/[Link] , declare pub mod formal; . In
01 The Big Picture
your test, call greet::formal::formal_hello("Alice") .
mod keyword
💡 Hint: When greet gets a submodule, src/[Link]
02
→ src/greet/[Link]. The mkdir command:
03 Modules to Files mkdir src/greet && mv src/[Link] src/greet/[Link].

04 Submodule Rule 🏆 Bonus: Add another submodule greet::casual with a different style of greeting. The directory should
VISIBILITY have three files: [Link], [Link], [Link].

05 pub keyword

06 Privacy Rules
PROBLEM 07 — Privacy Deep Dive
07 Privacy Examples
Reason About Visibility
PATHS & SCOPE
Without running it, predict which lines compile in this code. Then run it and check your
08 use keyword answers:
09 Glob & Multi-use

10 super keyword mod outer {


pub mod inner {
MASTERY
pub fn visible() {}
11 Full Walkthrough fn hidden() {}

12 Practice Problems
mod deep {
13 Cheatsheet pub fn deep_visible() {}
}
}
fn secret() {}
}

fn main() {
outer::inner::visible(); // Line A
outer::inner::hidden(); // Line B
outer::secret(); // Line C
outer::inner::deep::deep_visible(); // Line D
}

💡 Which lines compile? Apply the two rules: public items are accessible from any parent.
Private items are only accessible from the same module and its children. Note that deep is a
private module.

🏆 Bonus: Make all lines compile by adding/removing the minimum number of pub keywords.

PROBLEM 08 — Full Project

The Library + Binary Pattern

Build a small "todo" library with this structure: src/[Link] (declares modules),
src/todo/[Link] (the Todo struct and add/complete functions), src/todo/[Link]
(a pub fn print_all function). Create src/[Link] that imports the library, adds
three todos, completes one, and prints them all. The Todo struct should have a title:
String and done: bool field, both public.
CHAPTER 7
💡 Hint: Start with cargo new todos (binary). The library is src/[Link]. [Link] uses use
todos::todo::Todo (or however you name your crate). Run with cargo run.
Modules & Code
Organization

FOUNDATIONS

01 The Big Picture

02

03
mod keyword

Modules to Files
📋 Chapter 7 Complete Cheatsheet
04 Submodule Rule
DECLARE MODULE (INLINE) DECLARE MODULE (FILE)
VISIBILITY

05 pub keyword mod foo { mod foo;


fn bar() {} // body lives in src/[Link]
06 Privacy Rules
} // or src/foo/[Link]
07 Privacy Examples
PATHS & SCOPE

08 use keyword
MAKE THINGS PUBLIC CALL WITH FULL PATH
09 Glob & Multi-use

10 super keyword pub mod foo; module::function();


MASTERY pub fn bar() {} a::b::c::function();
pub struct Baz { // :: separates each level
11 Full Walkthrough pub field: i32 // fields also need pub!

12 Practice Problems }

13 Cheatsheet

USE — SHORTEN PATHS SUPER — NAVIGATE UP

use a::b::c; // use module super::func(); // parent module


use a::b::c::func; // use function super::mod_name; // parent's child
use a::{X, Y}; // multiple items use super::foo; // bring parent's foo in sc
use a::*; // glob (careful!)

FILE SYSTEM RULES

// Module foo with NO submodules:


src/[Link]

// Module foo WITH submodules (bar is a submodule):


src/foo/[Link] ← foo's code + declares mod bar;
src/foo/[Link] ← bar's code

// The module tree always matches the file tree!

PRIVACY RULES — QUICK REFERENCE

// Private (default) — accessible by:


// ✅ same module
// ✅ children of that module
// ❌ parent modules
// ❌ sibling modules
// ❌ external crates
CHAPTER 7 // Public (pub) — accessible by:
Modules & Code // ✅ everyone (if the whole path up is also pub)
Organization
// CRITICAL: BOTH the module AND the item must be pub!
pub mod foo; // ✅ module is public

FOUNDATIONS
pub fn bar() {} // ✅ function is public
// Only then can outsiders call foo::bar()
01 The Big Picture

02 mod keyword

03 Modules to Files

04 Submodule Rule ✅ You've mastered Chapter 7. The module system is the foundation for all larger Rust projects.
VISIBILITY Next: Chapter 8 — Common Collections (Vec, String, HashMap) — data structures that grow at
runtime.
05 pub keyword

06 Privacy Rules

07 Privacy Examples
PATHS & SCOPE

08 use keyword

09 Glob & Multi-use

10 super keyword
MASTERY

11 Full Walkthrough

12 Practice Problems

13 Cheatsheet

You might also like