DEV Community

Subesh Yadav
Subesh Yadav

Posted on

πŸ¦€ Day 10 of #100DaysOfRust – Mastering Paths, Visibility & Module Imports

As Rust projects grow in complexity, it's important to organize code clearly, manage visibility smartly, and use idiomatic import patterns. Today’s learning focused on:

  • Absolute & Relative paths
  • pub, super, use, as, *, and more
  • Privacy rules in structs, enums, functions, modules
  • Re-exporting & external crates

Let’s dive into each one πŸ‘‡

πŸ“ Absolute vs Relative Paths

Rust lets you access modules and items using:

βœ… Absolute paths – start from the crate root

crate::module::submodule::function();
Enter fullscreen mode Exit fullscreen mode

βœ… Relative paths – start from the current module

self::submodule::function();
super::parent_module::function();
Enter fullscreen mode Exit fullscreen mode

You can use them in both mod declarations and use imports.

πŸ” The pub Keyword – Managing Visibility

By default, everything is private in Rust β€” including modules, functions, structs, enums, and fields.

You must explicitly opt-in to make something public using the pub keyword.

πŸ”Ή Public vs Private: Modules & Functions

mod outer {
    pub mod inner {
        pub fn greet() {
            println!("Hello from inner!");
        }

        fn secret() {
            println!("This is private");
        }
    }

    fn outer_fn() {} // private to crate::outer
}

fn main() {
    outer::inner::greet(); // βœ…
    // outer::inner::secret(); ❌ won't compile
}
mod is private unless marked pub
Enter fullscreen mode Exit fullscreen mode

Functions are private to their module unless pub is used

You can access child modules from parent, but only if they’re pub

Child modules cannot access parent’s private items unless exposed

βœ… With Structs

You control visibility at the field level:

pub struct Flower {
    pub name: String, // public
    color: String,    // private
}
Enter fullscreen mode Exit fullscreen mode

Outside modules can create Flower but can only access the name field directly.

βœ… With Enums

Enums behave differently. If an enum is pub, all of its variants are also public:

pub enum Color {
    Red,
    Green,
}
Enter fullscreen mode Exit fullscreen mode

You cannot make individual enum variants private.

πŸ”Ό The super Keyword

Use super to refer to the parent module β€” helpful in nested module hierarchies.

// In src/garden/flowers.rs
fn bloom() {
    super::tools::water(); // Access tools module in parent garden
}
Enter fullscreen mode Exit fullscreen mode

This keeps your code modular and still lets you reach into parent modules when needed.

πŸ”§ The use Keyword – Clean Imports

Use use to bring items into scope. It avoids long paths and increases clarity.

use crate::garden::vegetables::Carrot;

fn main() {
    let _ = Carrot {};
}
Enter fullscreen mode Exit fullscreen mode

βœ… Idiomatic Grouping

use std::{io, cmp::Ordering};
Enter fullscreen mode Exit fullscreen mode

βœ… Use Aliases with as

use std::collections::HashMap as Map;

let mut map = Map::new();
Enter fullscreen mode Exit fullscreen mode

πŸ”„ Re-exporting with pub use

You can expose internal module items for cleaner APIs:

// garden/mod.rs
pub use self::vegetables::Tomato;

// main.rs
use crate::garden::Tomato;
Enter fullscreen mode Exit fullscreen mode

This is a powerful pattern when building libraries or modules where you want to hide internal structure.

πŸ“¦ Using External Crates

To use packages from crates.io:

Add to Cargo.toml:

rand = "0.8.5"
Enter fullscreen mode Exit fullscreen mode

Bring it into scope:

use rand::Rng;

let num = rand::thread_rng().gen_range(1..101);
Enter fullscreen mode Exit fullscreen mode

Now you can use functions and types from the crate.

✨ Glob Imports with *

You can bring all public items from a module:

use std::collections::*;
Enter fullscreen mode Exit fullscreen mode

⚠️ Use this sparingly to avoid confusion and potential conflicts. It’s often used in tests, preludes, or macro-heavy codebases.

🧠 Bonus: Idiomatic Use Patterns

Group related imports for readability:

use std::{fmt, io};
Enter fullscreen mode Exit fullscreen mode

Prefer pub use inside lib.rs or mod.rs to design clean APIs.

Avoid deeply nested paths in your main.rs β€” import what you need with use.

🧾 Summary

Today was all about Rust’s module system, path resolution, and visibility:

  • Absolute vs relative paths
  • pub, super, and privacy rules
  • Struct & enum visibility
  • Function and module scope
  • use, as, *, pub use
  • External crates
  • Idiomatic import practices

These patterns help keep Rust code organized, safe, and scalable β€” essential skills for real-world projects.

πŸ“… See you on Day 11 with more advanced Rust!

Top comments (0)