Rust :: Modules

Packages, Crates, and Modules

Modules

Inline

// making a item `pub` is known as "exporting"
mod mod_name {
    pub mod sub_mod_name {
        struct SomeStruct {}
        pub fn function() {}
        // available anywhere inside this crate, but not by other crate
        pub(crate) fn some() {}
        // only within this module or child module
        private_fn() {}
    }
}

In separate files

// expect some_mod.rs or some_mod/mod.rs
//  ";" indicates to load from a file
mod some_mod;

// example of module tree
root/
|--- main.rs
|--- mod1.rs
|--- mod2/
        |--- mod.rs
        |--- sub_mod1.rs
// to use mod1
// main.rs
mod mod1;
fn main() {
    mod1::some_pub_fn();
}

// to use mod2 and sub_mod1
// in mod2.rs
mod sub_mod1;
// in main.rs
mod mod2;
fn main() {
    mod2::sub_mod1::some_pub_fn();
}

Path

// absolute path
crate::mod_1::mod_2::some_pub_fn()

// starting with :: refers to an external crate
use ::image::Pixels;    // the `image` crate's `Pixel`

// relative path
super::child_mod::some_pub_fn()
self::child_mod     // relative to current

// "use" bring a path into scope
// idomatic path - bring parent scope
use std::fmt;
use std::io;
fn function1() -> fmt::Result {}
fn function2() -> io::Result<()> {}

// use as
use std::io::Result as IoResult;

// anonymous
// bring b anonymously into scope
// useful for traits with conflicting names
use a::b as _;

// pub use can allow external code to use
pub use crate::some_mod

// use external crate
// define in Cargo.toml
[dependencies]
clap = "3.0.0"
// main.rs
use clap::Mod;


// nested use
use std::io::{self, Write};

// use inside a mod
mod some_mod {
    pub use self::sub_mod::field as fav
    pub mod sub_mod {
        pub const field: &'static str =  "Value";
    }
}
fn main() {
    some_mod::fav;
}

Privacy

// for Struct, each field is private by default
// for Enum, each variant is public by default if the enum is made pub
pub mod some_mod {
    pub struct SomeStruct {
        pub name: String,
        email: String, // email is private
    }
    pub enum SomeEnum {
        Var1,
        Var2, // both are pub now
    }
    pub fn some_fn() {}
}

Package Layout

├── Cargo.lock
├── Cargo.toml
├── src/
│   ├── lib.rs
│   ├── main.rs
│   └── bin/
│       ├── named-executable.rs
│       ├── another-executable.rs
│       └── multi-file-executable/
│           ├── main.rs
│           └── some_module.rs
├── benches/
│   ├── large-input.rs
│   └── multi-file-bench/
│       ├── main.rs
│       └── bench_module.rs
├── examples/
│   ├── simple.rs
│   └── multi-file-example/
│       ├── main.rs
│       └── ex_module.rs
└── tests/
    ├── some-integration-tests.rs
    └── multi-file-test/
        ├── main.rs
        └── test_module.rs

Modular Code

# Cargo.toml
[lib]
name = "mylib" # default to pkg name
path = "src/lib.rs" // defaule root module

[[bin]]
name = "mybin" # default to pkg name
path = "src/bin/mybin.rs" # defualt src/main.rs