Hone logo
Hone
Problems

Building a Simple Rust Module System

Rust's module system is a fundamental concept for organizing code, promoting reusability, and managing complexity. This challenge will guide you through creating a simplified version of Rust's module system, allowing you to understand its core principles by implementing them yourself.

Problem Description

Your task is to create a Rust program that simulates a basic module system. This system should allow you to define modules, declare items (functions and structs) within them, and make those items publicly accessible from outside their defining module. You'll need to handle module nesting and ensure that only public items can be accessed.

Key requirements:

  • Module Declaration: Be able to declare a new module using a specific keyword or syntax.
  • Item Declaration: Define functions and structs within modules.
  • Visibility Control: Implement public (pub) and private (default) visibility for items.
  • Module Nesting: Support creating modules within other modules.
  • Item Access: Allow accessing public items from parent modules or the top-level scope.
  • Error Handling: Gracefully handle attempts to access private items or non-existent items.

Expected behavior:

  • Code within a module can access all items (public and private) within that same module.
  • Code outside a module can only access items explicitly declared as pub.
  • Nested modules should inherit access rules from their parent.

Examples

Example 1: Basic Module and Public Function

Input: (Conceptual code structure - Rust syntax will be used for actual implementation)

// main.rs
mod greetings {
    pub fn hello() {
        println!("Hello from greetings module!");
    }
    fn private_message() {
        println!("This is a private message.");
    }
}

fn main() {
    greetings::hello();
    // greetings::private_message(); // This should cause a compile-time error
}

Output:

Hello from greetings module!

Explanation: The hello function is declared pub within the greetings module, making it accessible from main.rs. The private_message function is not pub, so it cannot be accessed from outside its module.

Example 2: Nested Modules and Struct Access

Input:

// main.rs
mod shapes {
    pub mod circle {
        pub struct Circle {
            pub radius: f64,
        }
        impl Circle {
            pub fn new(radius: f64) -> Self {
                Self { radius }
            }
        }
        fn internal_helper() {
            println!("Calculating area...");
        }
    }
    mod square {
        // This module and its contents are private by default
        pub fn area(side: f64) -> f64 {
            side * side
        }
    }
}

fn main() {
    let my_circle = shapes::circle::Circle::new(5.0);
    println!("Circle radius: {}", my_circle.radius);
    // let _ = shapes::circle::internal_helper(); // Should error
    // let _ = shapes::square::area(4.0); // Should error
}

Output:

Circle radius: 5.0

Explanation: The shapes::circle module is public, and the Circle struct and its new method are also public, allowing instantiation and access to the radius field from main.rs. The internal_helper function is private to shapes::circle. The shapes::square module is private to shapes, and even if it weren't, its area function is not public, so it cannot be accessed from main.rs.

Example 3: Attempting to Access Private Item

Input:

// main.rs
mod data {
    fn secret_value() -> u32 {
        42
    }
}

fn main() {
    // let value = data::secret_value(); // This should cause a compile-time error
    println!("Attempting to access a private value would fail.");
}

Output:

Attempting to access a private value would fail.

Explanation: The secret_value function is not marked pub, making it private to the data module. An attempt to call it from main.rs would result in a compilation error.

Constraints

  • Your module system implementation should be purely in Rust code. You are not expected to modify the Rust compiler itself.
  • You will need to define your own structures and logic to represent modules, items, and their visibility.
  • Focus on the conceptual implementation of module scoping and visibility rather than complex features like conditional compilation or macros.
  • The solution should be reasonably efficient and not introduce excessive overhead for simple module operations.

Notes

  • Think about how you can represent modules and their contents in your data structures.
  • Consider how to track the visibility of items and enforce access rules.
  • You might want to start with a flat module structure before tackling nested modules.
  • Rust's pub keyword is the primary mechanism for controlling visibility. Your system should mimic this.
  • This challenge is about understanding the principles behind Rust's module system. You'll be building a simplified abstraction.
Loading editor...
rust