[Avg. reading time: 6 minutes]

Module Subfolders

This is the production-style way to organize Rust modules.

A folder becomes a module when it contains a mod.rs file (or in newer style, when departments.rs exists and points to departments/ files, but mod.rs is still common in many codebases).

Key idea:

  • mod.rs contains the module root for that folder
  • Other .rs files inside the folder become submodules when declared using mod (or pub mod)
  • Items are private by default
  • Use pub to expose modules or functions to parent modules

cargo new moddemo3

create the following directory structure

main.rs

mod departments; tells Rust to load src/departments/mod.rs.

mod departments;

fn main() {
    println!("{:?}", get_standard_greetings());
    departments::sales::meet_customer(1);
    departments::service::meet_customer(3);
}

fn get_standard_greetings() -> String {
    return "Welcome to our store.".to_string();
}

or

mod departments;

use crate::departments::{sales, service};

fn main() {
    println!("{}", get_standard_greetings());
    sales::meet_customer(1);
    service::meet_customer(3);
}

fn get_standard_greetings() -> String {
    "Welcome to our store.".to_string()
}

crate keyword refers to the root of the current program (crate)

departments > mod.rs

fn get_number(num: i32) -> String {
    match num {
        1 => return "123-456-7890".to_string(),
        2 => return "987-654-3210".to_string(),
        _ => return "000-000-0000".to_string(),
    }
}

pub mod sales;
pub mod service;

#[cfg(test)]
mod tests; // Only compiles when running tests

departments > sales.rs

pub fn meet_customer(num: i32) {
    println!("Sales : meet customer {num}");
    let phone_number = super::get_number(num);
    println!("Sales calling {}", phone_number);
}

departments > service.rs

pub fn meet_customer(num: i32) {
    println!("Service : meet customer {num}");
    let phone_number = super::get_number(num);
    let ticket_number = self::get_service_ticket_number(num);
    println!("Calling {phone_number} with ticket number {ticket_number}");
}

fn get_service_ticket_number(num: i32) -> i32 {
    match num {
        1 => return 2452423,
        2 => return 2341332,
        _ => return 6868765,
    }
}

departments > tests.rs

use crate::get_standard_greetings;

#[test]
fn test_customerphone() {
    assert_eq!("000-000-0000", super::get_number(4));
}

#[test]
fn test_standard_greeting() {
    assert_eq!("Welcome to our store.", get_standard_greetings());
}

cargo run
cargo test

Read more

#module #subfoldersVer 2.0.19

Last change: 2026-03-04