Lesson 7.3 · 8 min
Splitting code into modules
Chatterbox is one file and it is getting long. Rust lets you put related code in named boxes called modules, and decide what each box shows to the rest of the program.
Adds to Chatterboxmessage.rs and command.rs split out of main.rs.
Boxes with a front door
Chatterbox now has a message type, a command parser and an error type. Everything sits in one list in main.rs. A module is a named box around some of that code. Writing mod message { ... } creates a box called message.
The rule that makes boxes useful: everything inside is private by default. Code outside the box cannot see it. You choose what to show by writing pub (short for public) in front of it. That way message can keep its details to itself and only offer a small, stable surface.
error[E0616]: field `text` of struct `Message` is private --> src/main.rs:15:22 | 15 | println!("{}", m.text); | ^^^^ private field
The struct is pub, so main may name it and call new. The field text is not, so it is off limits. Two fixes: write pub text: String to show it, or add a pub fn text(&self) -> &str that shows it on your terms. The second keeps the freedom to change how the text is stored later.
Walking in with use
Outside a module you reach its items with a path: message::Message. Typing that every time gets tiring, so use message::Message; brings the name into scope once. It is the same job as Python's from message import Message.
This listing is trimmed to the part this lesson is about; the commands from earlier chapters (/say, /history, /stats, /long) and the per-author counts are still in your project.
$ cargo run
sam: /help
Some(Help)
Last(3)From mod to file
Everything above lived in one file so you can run it in the browser. In a real Cargo project the box usually becomes a file. Take the body of mod message { ... }, move it into src/message.rs, and replace it in main.rs with the single line mod message;. The semicolon form tells Rust "this module's contents are in the file with the same name". Nothing else changes: pub and use work exactly as before.
chatterbox/
Cargo.toml
src/
main.rs // mod message; mod command; fn main() {...}
message.rs // Message
command.rs // Command, parse
An outside module can only reach into another one through its pub items, which is why file boundaries stay clean as a project grows.
Finish command::parse. /help and /quit give their variants, /last N gives Last(N) when N is a number, and everything else (including /last x) gives None. Use strip_prefix, which returns the rest of the text if the prefix is there.
Finish command::parse. /help and /quit give their variants, /last N gives Last(N) when N is a number, and everything else (including /last x) gives None. Use strip_prefix, which returns the rest of the text if the prefix is there.
Hidden tests (4): last_with_a_number help_and_quit last_with_junk_is_none plain_text_is_none
This exercise runs real Rust in your browser through the official Rust Playground, so it needs JavaScript.
What you have now
Chatterbox has two named boxes with a small public surface each. As a preview, the next lesson writes the history to disk so it is still there tomorrow.
Say it out loud, then reveal
What is the default visibility of an item inside a mod?Reveal
What does `mod message;` (with a semicolon) mean in main.rs?Reveal
What does use do?Reveal
That is lesson 7.3. Tick it off so the course remembers where you are.