# Modules

## 01. In same file

Related code and data are grouped into a module and stored in the same file.

```rust
fn main() {
   greetings::hello();
}

mod greetings {
  // ⭐️ By default, everything inside a module is private
  pub fn hello() { // ⭐️ So function has to be public to access from outside
    println!("Hello, world!");
  }
}
```

Modules can also be nested.

```rust
fn main() { 
  phrases::greetings::hello();
}

mod phrases { 
  pub mod greetings { 
    pub fn hello() { 
      println!("Hello, world!");
    }
  }
}
```

Private functions can be called from the same module or from a child module.

```rust
// 01. Calling private functions of the same module
fn main() {
  phrases::greet();
}

mod phrases {
  pub fn greet() {
    hello(); //or self::hello();
  }

  fn hello() {
    println!("Hello, world!");
  }
}

// 02. Calling private functions of the parent module
fn main() {
  phrases::greetings::hello();
}

mod phrases {
  fn private_fn() {
    println!("Hello, world!");
  }

  pub mod greetings {
    pub fn hello() {
      super::private_fn();
    }
  }
}
```

> 💡 `self` keyword is used to refer same module, while `super` keyword is used to refer parent module. Also `super` keyword can be used to access root functions from inside a module.

```rust
fn main() {
  greetings::hello();
}

fn hello() {
  println!("Hello, world!");
}

mod greetings {
  pub fn hello() {
    super::hello();
  }
}
```

> 🔎 When writing tests it’s a good practice to write tests inside a test module because of they compile only when running tests.

```rust
fn greet() -> String {
    "Hello, world!".to_string()
}

#[cfg(test)] // only compiles when running tests
mod tests {
    use super::greet; // import root greet function

    #[test]
    fn test_greet() {
        assert_eq!("Hello, world!", greet());
    }
}
```

## 02. In different file, same directory

```rust
// ↳ main.rs
mod greetings; // import greetings module

fn main() {
  greetings::hello();
}

// ↳ greetings.rs
// ⭐️ no need to wrap the code with a mod declaration. File itself acts as a module.
pub fn hello() { // function has to be public to access from outside
  println!("Hello, world!");
}
```

If we wrap file content with a `mod` declaration, it will act as a nested module.

```rust
// ↳ main.rs
mod phrases;

fn main() {
  phrases::greetings::hello();
}

// ↳ phrases.rs
pub mod greetings { // ⭐️ module has to be public to access from outside
  pub fn hello() {
    println!("Hello, world!");
  }
}
```

## 03. In different file, different directory

`mod.rs` in the directory module root is the entry point to the directory module. All other files in that directory root, act as sub-modules of the directory module.

```rust
// ↳ main.rs
mod greetings;

fn main() {
  greetings::hello();
}

// ↳ greetings/mod.rs
pub fn hello() { // ⭐️ function has to be public to access from outside
  println!("Hello, world!");
}
```

Again, If we wrap file content with a `mod` declaration, it will act as a nested module.

```rust
// ↳ main.rs
mod phrases;

fn main() {
  phrases::greetings::hello();
}

// ↳ phrases/mod.rs
pub mod greetings { // ⭐️ module has to be public to access from outside
  pub fn hello() {
    println!("Hello, world!");
  }
}
```

Other files in the directory module act as sub-modules for `mod.rs`.

```rust
// ↳ main.rs
mod phrases;

fn main() {
  phrases::hello()
}

// ↳ phrases/mod.rs
mod greetings;

pub fn hello() {
  greetings::hello()
}

// ↳ phrases/greetings.rs
pub fn hello() {
  println!("Hello, world!");
}
```

⭐️ If you need to access an element of `phrases/greetings.rs` from outside the module, you have to import `greetings` module as a public module.

```rust
// ↳ main.rs
mod phrases;

fn main() {
    phrases::greetings::hello();
}

// ↳ phrases/mod.rs
pub mod greetings;  // ⭐️ `pub mod` instead `mod`

// ↳ phrases/greetings.rs
pub fn hello() {
  println!("Hello, world!");
}
```

> 🔎 It’s unable to import child file modules of directory modules to `main.rs`, so you can’t use `mod phrases::greetings;` from `main.rs`. But there is a way to import `phrases::greetings::hello()` to `phrases` module by re-exporting `hello` to `phrases` module. So you can call it directly as `phrases::hello()`.

```rust
// ↳ phrases/greetings.rs
pub fn hello() {
  println!("Hello, world!");
}

// ↳ phrases/mod.rs
pub mod greetings;

pub use self::greetings::hello; //re-export greetings::hello to phrases

// ↳ main.rs
mod phrases;

fn main() {
    phrases::hello(); //you can call hello() directly from phrases
}
```

This allows you to present an external interface that **may not directly map** to your internal code organization. If still it is not clear, don’t worry; We discuss the usages of `use` on an upcoming section in this post.
