# Modules

* Use `pub` keyword to make items public.
* Use `use` keyword to brings a path into scope.
* Use `as` keyword to make alias for a path that brought to scope by using `use`.
* A path can take two forms:
  * An absolute path is the full path starting from a crate root; for code from an external crate, the absolute path begins with the crate name, and for code from the current crate, it starts with the literal `crate`.
  * A relative path starts from the current module and uses `self`, `super`, or an identifier in the current module.
* References:
  * [The Module System](https://doc.rust-lang.org/book/ch07-00-managing-growing-projects-with-packages-crates-and-modules.html)
  * [Defining Modules to Control Scope and Privacy](https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html)
  * [Bringing Paths into Scope with the use Keyword](https://doc.rust-lang.org/book/ch07-04-bringing-paths-into-scope-with-the-use-keyword.html)

## modules1.rs

```rust
// TODO: Fix the compiler error about calling a private function.
mod sausage_factory {
    // Don't let anybody outside of this module see this!
    fn get_secret_recipe() -> String {
        String::from("Ginger")
    }

    pub fn make_sausage() {
        get_secret_recipe();
        println!("sausage!");
    }
}

fn main() {
    sausage_factory::make_sausage();
}
```

* This exercise is simple we just need to make the `make_sausage` function accessible from main function but not the `get_secret_recipe` function.
* We can do this by adding `pub` before `fn make_sausage()`.

## modules2.rs

```rust
// You can bring module paths into scopes and provide new names for them with
// the `use` and `as` keywords.

mod delicious_snacks {
    // TODO: Add the following two `use` statements after fixing them.
    pub use self::fruits::PEAR as fruit; // as fruit and add pub
    pub use self::veggies::CUCUMBER as veggie; // as veggie and add pub

    mod fruits {
        pub const PEAR: &str = "Pear";
        pub const APPLE: &str = "Apple";
    }

    mod veggies {
        pub const CUCUMBER: &str = "Cucumber";
        pub const CARROT: &str = "Carrot";
    }
}

fn main() {
    println!(
        "favorite snacks: {} and {}",
        delicious_snacks::fruit,
        delicious_snacks::veggie,
    );
}
```

*   In this exercise the `TODO` stated that we need to complete the `use` syntax below:

    ```rust
    use self::fruits::PEAR as ???;
    use self::veggies::CUCUMBER as ???;
    ```
* So we can conclude that we need to re-export the constant `PEAR` as `fruit` and `CUCUMBER` as `veggie`.
* Don forget to add `pub` so it's accessible in main function.

## modules3.rs

```rust
// You can use the `use` keyword to bring module paths from modules from
// anywhere and especially from the standard library into your scope.

// TODO: Bring `SystemTime` and `UNIX_EPOCH` from the `std::time` module into
// your scope. Bonus style points if you can do it with one line!
// use ???;

use std::time::SystemTime;
use std::time::UNIX_EPOCH;

fn main() {
    match SystemTime::now().duration_since(UNIX_EPOCH) {
        Ok(n) => println!("1970-01-01 00:00:00 UTC was {} seconds ago!", n.as_secs()),
        Err(_) => panic!("SystemTime before UNIX EPOCH!"),
    }
}
```

* In this exercise we need to bring `SystemTime` and `UNIX_EPOCH` into main scope.
*   We can do this by using `use` like below:

    ```rust
    use std::time::SystemTime;
    use std::time::UNIX_EPOCH;
    ```
