Rust modules

Referance : Modules - Rust By Example

Rust uses a module system to organize and manage code across multiple files and crates. The module system helps in code encapsulation, reusability, and namespace management.

What is a Module in Rust?

A module in Rust is a way to group related functions, structs, enums, traits, and even other modules together.

  • Modules help avoid name conflicts by creating separate namespaces.
  • Modules enable code organization by allowing developers to structure code logically.
  • Modules support encapsulation using pub to control visibility.


  1. Use modules to organize code logically (e.g., separate API logic, database logic, etc.).
  2. Use "pub" carefully to control access and avoid exposing unnecessary internals.
  3. Use "use" smartly to simplify code without polluting the namespace.
  4. Structure files properly using folders and "mod.rs" for better readability.


Lets learn :

  • How to define and use modules (mod)
  • How to control visibility (pub)
  • How to structure files and folders
  • How to use use, super, and crate


Declaring and Using Modules

2.1 Declaring Modules

A module can be declared using the mod keyword:

Ex for simple module :

mod greetings {
    pub fn chant() {
        println!("Jai Shree Ram!");
    }
}

fn main() {
    greetings::chant();
}
/*Jai Shree Ram!*/        

Nested Modules:

Modules can be nested within other modules:

mod outer {
    pub mod inner {
        pub fn say_hello() {
            println!("Jai Bajrang Bali!");
        }
    }
}

fn main() {
    outer::inner::say_hello();
}
/*
Jai Bajrang Bali!
*/        

Controlling Visibility (pub)

By default, all items inside a module are private. You need pub to make them accessible outside the module.

mod my_module {
    fn private_function() {
        println!("Jai Shree Ram -This is private!");
    }

    pub fn public_function() {
        println!("Om Namah Shivaya - This is public!");
    }
}

fn main() {
    // my_module::private_function(); // ❌ ERROR: function is private
    my_module::public_function(); // ✅ Works because it is public
}
/*
Om Namah Shivaya - This is public!
*/        

Making a Struct’s Fields Public

In Rust, when a struct has private fields, you can't directly initialize those fields from outside the module.

mod my_module {
    pub struct Person {
        pub name: String,
        age: u32, // This field is private
    }
}

fn main() {
    /*
    If you uncomment below code it cause the ❌ ERROR: 
    The reason is age is private and cant be used.

    let person = my_module::Person {
        name: "Alice".to_string(),
        //age: 30, // ❌ ERROR: `age` is private
    };
   */
    println!("Person's name: {}", person.name);
}         

However, we can provide a public constructor function within the module to initialize the struct.

Here's how you can modify above code to include a constructor function for the Person struct:

mod my_module {
    pub struct Person {
        pub name: String,
        age: u32, // This field is private
    }
    impl Person {
        // Public constructor function to initialize the struct
        pub fn new(name: String, age: u32) -> Person {
            Person { name, age }
        }

        // Public method to access the private field
        pub fn get_age(&self) -> u32 {
            self.age
        }
    }
}

fn main() {
    let person = my_module::Person::new("Jai ShreeRam".to_string(), 30);;
    println!("Person's name: {}", person.name);
    println!("Person's age: {}", person.get_age());
}
/*
Person's name: Jai ShreeRam
Person's age: 30
*/        

Module Files and Folders

Rust modules can be split across multiple files.

Creating Modules in Separate Files

Instead of writing all modules in one file, Rust allows you to structure your project like this:

src/
│── main.rs
│── my_module.rs        

Linking my_module.rs

In main.rs, declare the module:

File: main.rs

mod my_module; // Rust will look for my_module.rs

fn main() {
    my_module::say_hello();
}        

Then, in my_module.rs:

File: my_module.rs

pub fn say_hello() {
    println!("Jai Shree Ram!");
}        

Using Submodules (mod.rs)

When a module has submodules, Rust allows you to structure it using folders.

Example Directory Structure

src/
│── main.rs
│── my_module/
│   │── mod.rs
│   │── sub_module.rs         

File: main.rs

mod my_module;

fn main() {
    my_module::sub_module::say_hello();
}        

File: my_module/mod.rs

pub mod sub_module;        

File: my_module/sub_module.rs

pub fn say_hello() {
    println!("Jai Shree Ram sub_module!");
}        

The use Keyword: Bringing Items into Scope

If a module is deeply nested, you can use use to make code shorter.

use imports greet directly, so we don’t need outer::inner:: every time.

use outer::inner::greet;

mod outer {
    pub mod inner {
        pub fn greet() {
            println!("Jai Shree Ram from inner!");
        }
    }
}

fn main() {
    greet();
}        

The super Keyword: Accessing Parent Modules

You can use super to refer to the parent module.

mod parent {
    pub mod child {
        pub fn greet() {
            super::say_hello();  // super keyword is used here 
        }
    }

    pub fn say_hello() {
        println!("Jai Shree Ram from parent!");
    }
}

fn main() {
    parent::child::greet();
}        

The crate Keyword: Accessing Root Module

The crate keyword refers to the root module.

mod my_module {
    pub fn greet() {
        crate::say_hello(); // crate is used here
    }
}

fn say_hello() {
    println!("Jai Shree Ram from root!");
}

fn main() {
    my_module::greet();
}        

Modules and Crates

  • A crate is a package of Rust code that can be compiled into a binary or library.
  • A module is a namespace within a crate.
  • The crate:: keyword refers to the root of the crate.

Example: Using External Crates

[dependencies]
rand = "0.8"        
use rand::Rng; // Import from external crate

fn main() {
    let num: i32 = rand::thread_rng().gen_range(1..10);
    println!("Random number: {}", num);
}        

To view or add a comment, sign in

More articles by Amit Nadiger

  • Dvb-APIs

    The Linux Digital Video Broadcasting (DVB) APIs serve as the critical bridge between user applications and kernel-level…

  • Satellite Communication Basics w.r.t TV

    Main Highlights RF: Raw satellite signal (10.7-12.

  • Actor Design Pattern in Rust

    What Is the Actor Design Pattern? The Actor model is a concurrency design pattern in which: Each Actor runs in its own…

  • Mock and Stub in Android

    In Android unit testing, the ability to replace dependencies with test doubles is crucial for effective and isolated…

  • Integrating C and Rust

    Interfacing Rust with existing C code is one of the most common and powerful real-world uses of Rust: you get Rust’s…

  • Const generics

    Const generics in Rust allow us to use a value (like a number) as a generic parameter, in addition to types and…

  • HRTB - Higher-Ranked Trait Bounds

    As you know lifetimes are a core feature of the Rust language, which will enforce that references do not outlive the…

  • K8s basics

    What is Kubernetes? Kubernetes is an open-source container orchestration platform. It helps to deploy, manage, scale…

  • Atomics in Rust

    In computer science, Atomic is used to describe an operation that is indivisible: it is either fully completed, or it…

  • Docker Workflow for a Rust Axum App

    Basic Docker Workflow Write code (e.g.

Explore content categories