Dividing Code Into Modules

Learn how to divide our code into modules using single-file modules.

We can write huge programs in one file, but dividing our code into smaller sections—known as modules in Rust—offers significant advantages:

  • It’s much easier to find our map functionality in a file named map.rs than it is to remember that it’s somewhere around line 500 of an ever-growing main.rs.
  • Cargo can compile modules concurrently, producing much better compilation times.
  • Bugs are easier to find in self-contained code that limits linkages to other sections of code.

Modules may either be a single .rs file or a directory.

Crates and modules

Rust programs are divided into crates and modules. Crates are large groups of code with their own Cargo.toml file.

Our game is a crate. So is bracket-lib; every dependency we specify in Cargo is a crate. Crates are largely independent of one another but may each have dependencies upon other crates and use code from them.

A module is a section of code within a crate, identified in a separate file or directory. We can make our game code more navigable by grouping related code, like placing all map-related code inside a map module.

Crates and modules act as namespaces. bracket-lib::prelude refers to the bracket-lib crate’s prelude module. We can reference the current crate with crate::. For example, once we have a map module, we can refer to it with crate::map anywhere within our program. Modules form a hierarchy, with the crate at the top. Modules can contain other modules, and their namespaces grow to match. For example, with map::region or map::region::chunk, we can continually nest downwards. Crates, modules, and scopes relate to each other like this:

Get hands-on with 1400+ tech skills courses.