In Rust, what is the purpose of a mod.rs file?

15,168

Solution 1

Imagine the following directory structure:

code/
  `- main.rs
   - something/
     `- mod.rs

If in main.rs you do mod something;, then it'll look in the something/mod.rs file to use as the contents of the module declaration for something.

The alternative to this is to have a something.rs file in the code/ directory.

So to recap, when you write an empty module declaration such as mod something;, it looks either in:

  • a file called something.rs in the same directory
  • a file called mod.rs in a folder called something in the same directory

It then uses the contents of either of those files to use as the contents of the module declaration.

Solution 2

I find modules are particularly poorly explained in documentations of many languages, despite being a base requirement.

If you know python or javascript

You may think of mod.rs as __init__.py in python or index.js in javascript. But there is a bit more to it in rust.

In Rust, folders are not immediately ready to use as modules.

You have to explicitly inform rust that they are available at a certain path in the file system.

That's the purpose of mod.rs.


You may also use a file with the same name as the folder. It should be clearer with an example:

src
    utils
        bar.rs
        foo.rs
    main.rs

At this point, the compiler doesn't know about foo.rs and bar.rs.

To expose them, you need to use either of the following options:

  • a file named mod.rs, inside of the utils folder
  • a file named utils.rs (same name as the folder), at the same level as the utils folder

Whatever option you choose, the file must then explicitly expose files that should be usable outside of the utils folder.

To expose both bar and foo, the content of mod.rs (or utils.rs) should be:

pub mod bar;
pub mod foo;

Based on what solution you choose, the resulting file structure should be:

With mod.rs:

src
    utils
        bar.rs
        foo.rs
        mod.rs
    main.rs

With <folder_name>.rs:

src
    utils
        bar.rs
        foo.rs
    utils.rs
    main.rs

Usage in main.rs:

mod utils;
use utils::{foo, bar};

EDIT:

It is now recommended to use the latter solution (<folder_name>.rs).

From the Rust reference:

Note: Previous to rustc 1.30, using mod.rs files was the way to load a module with nested children. It is encouraged to use the new naming convention as it is more consistent, and avoids having many files named mod.rs within a project.

(Thanks to MarkusToman for bringing this to my attention)

Share:
15,168

Related videos on Youtube

Liam Marshall
Author by

Liam Marshall

Updated on September 23, 2021

Comments

  • Liam Marshall
    Liam Marshall over 2 years

    In some Rust projects I've seen (i.e pczarn/rustboot), I've seen mod.rs files in directories for whatever reason. I've not been able to find documentation about this, and I've seen it in many other Rust projects. What is the purpose of a mod.rs file, and when should I use it?

  • Liam Marshall
    Liam Marshall over 9 years
    Could I use any filename instead of mod.rs, or is that a builtin.
  • Jorge Israel Peña
    Jorge Israel Peña over 9 years
    You can specify any path you want using the #[path = "thefile.rs"] attribute, but it's generally discouraged since the convention is what I specified in my answer. See the reference.
  • Markus Toman
    Markus Toman over 2 years
    Thanks, the Rust book is really weak in this regards. When you expose foo and bar, do you then do use utils::foo or just use foo? I would suspect the latter?
  • Markus Toman
    Markus Toman over 2 years
    I just found in doc.rust-lang.org/reference/items/… that "Note: Previous to rustc 1.30, using mod.rs files was the way to load a module with nested children. It is encouraged to use the new naming convention as it is more consistent, and avoids having many files named mod.rs within a project."
  • Romain Vincent
    Romain Vincent over 2 years
    @MarkusToman To use foo and bar in a file (main.rs for example), you need to bring the module in scope with mod utils; and then use utils::{foo, bar};
  • Vikas Goel
    Vikas Goel over 2 years
    1. What happens when both the files are present? something.rs and something/mod.rs? 2. Isn't that weird that every file's default name is expected to be mod.rs, making search a horrible experience?
  • Jagger Yu
    Jagger Yu almost 2 years
  • Abhijit Sarkar
    Abhijit Sarkar almost 2 years
    What if I don't want a nested directory but want to put the other files at the same level as main.rs?