Rust LogoDefining Modules to Control Scope and Privacy

Rust's module system is a fundamental feature for organizing code, controlling visibility (privacy), and preventing name collisions within larger projects. Modules allow you to encapsulate related code into logical units, forming a tree-like hierarchy that mirrors your project's structure.

1. Scope Control:
Modules primarily define a scope, creating distinct namespaces:
* Organization: They group related functions, structs, enums, constants, and even other modules. This makes large codebases more manageable and easier to navigate.
* Preventing Name Collisions: Each module has its own namespace. This means you can have functions or types with the same name in different modules without conflict (e.g., `garden::flowers::rose` and `bakery::cakes::rose`).
* Hierarchy: Modules form a tree, starting from the crate root (usually `src/main.rs` or `src/lib.rs`). A module can contain submodules, creating a clear hierarchical structure. You can reference items within the module tree using paths, similar to file system paths (e.g., `crate::garden::vegetables::Asparagus`).
* `crate`: Refers to the root of the current crate.
* `super`: Refers to the parent module.
* `self`: Refers to the current module.

2. Privacy Control:
Modules enforce strict privacy rules by default, allowing you to hide implementation details and expose only the necessary public API. This is crucial for maintaining abstraction and preventing unintended side effects.

* Default Privacy (Private by Default): By default, all items (functions, structs, enums, constants, modules) defined within a module are *private* to that module. This means they cannot be accessed by code outside of their immediate parent module unless explicitly made public. This is a core principle in Rust design, promoting well-defined interfaces.
* `pub` Keyword: To make an item visible and accessible from its parent module *and any ancestor module* in the module tree, you must explicitly mark it with the `pub` keyword.
* `pub fn`: Makes a function public.
* `pub struct`: Makes a struct public.
* `pub enum`: Makes an enum public.
* `pub mod`: Makes a submodule public, allowing code outside the parent module to access its (public) contents.
* Fields of `struct` and `enum` variants: For structs, marking the struct itself as `pub` does *not* automatically make its fields public. You must explicitly mark individual fields as `pub` (e.g., `pub name: String`). Similarly, for enum variants, you might need `pub` for their fields if they hold data.
* `use` Keyword: The `use` keyword doesn't change privacy; it's a convenience feature to bring items into the current scope, allowing you to refer to them by a shorter name rather than their full path. For example, `use crate::garden::vegetables::Asparagus;` allows you to refer to `Asparagus` directly.
* Re-exporting with `pub use`: You can use `pub use` to bring an item into scope and simultaneously make it public from the *current* module. This is useful for creating a more convenient public API where users don't need to know the exact internal module structure. For example, `pub use crate::garden::vegetables::Asparagus;` within the `garden` module would allow users to access `garden::Asparagus` directly.

By judiciously using `mod` and `pub`, you can design robust and maintainable Rust applications with clear interfaces and hidden internal complexities.

Example Code

// src/main.rs - The crate root

// Define a top-level module named 'garden'
mod garden {
    // Define a submodule 'vegetables' within 'garden'
    pub mod vegetables {
        // A public struct 'Asparagus'
        pub struct Asparagus {
            pub name: String, // Public field, accessible from anywhere that can access Asparagus
            id: u32,          // Private field, only accessible within the 'vegetables' module
        }

        impl Asparagus {
            // Public constructor for Asparagus
            pub fn new(name: String, id: u32) -> Asparagus {
                Asparagus { name, id }
            }

            // Public function to print asparagus name
            pub fn print_asparagus_name(&self) {
                println!("The asparagus's name is: {}", self.name);
                self.internal_helper(); // Calling a private method from within its own module is allowed
            }

            // Private function, only accessible within 'vegetables' module
            fn internal_helper(&self) {
                println!("Internal helper for asparagus ID: {}", self.id);
            }
        }
    }

    // A public function within the 'garden' module
    pub fn plant_garden() {
        println!("--- Planting the garden ---");

        // Use the public struct from the 'vegetables' submodule
        // We need to use the full path because 'vegetables' is a sibling module
        let my_asparagus = vegetables::Asparagus::new(String::from("Green Asparagus"), 1);

        // Accessing a public field is allowed
        println!("Planted: {}", my_asparagus.name);

        // Calling a public method
        my_asparagus.print_asparagus_name();

        // Calling a private method from a parent/sibling module is NOT allowed
        // my_asparagus.internal_helper(); // This would cause a compile error: method `internal_helper` is private

        println!("--- Garden planted ---");
    }

    // A private function within the 'garden' module
    fn garden_internal_function() {
        println!("This is a private garden internal function, only visible within 'garden'.");
    }
}

// In the main function (crate root)
fn main() {
    println!("Hello from the main function!");

    // Call the public function from the 'garden' module
    garden::plant_garden();

    // Attempting to call a private function from the 'garden' module is NOT allowed from `main`
    // garden::garden_internal_function(); // This would cause a compile error: function `garden_internal_function` is private

    // Attempting to create Asparagus directly and access private fields from 'main' (crate root)
    // The `id` field is private, so direct initialization like this is not allowed.
    // let direct_asparagus = garden::vegetables::Asparagus {
    //     name: String::from("Wild Asparagus"),
    //     id: 2, // This would cause a compile error: field `id` of struct `Asparagus` is private
    // };

    // You can create it using the public constructor, and access its public fields
    let another_asparagus = garden::vegetables::Asparagus::new(String::from("Purple Asparagus"), 3);
    println!("Another asparagus name: {}", another_asparagus.name);
    // Attempting to access a private field directly
    // println!("Another asparagus id: {}", another_asparagus.id); // This would cause a compile error: field `id` of struct `Asparagus` is private

    // Attempting to call a private function from the 'vegetables' module directly
    // garden::vegetables::Asparagus::new(String::from("test"), 0).internal_helper(); // This would cause a compile error: method `internal_helper` is private

    println!("Program finished.");
}