Modules Structure
External link: https://doc.rust-lang.org/stable/book/ch07-02-defining-modules-to-control-scope-and-privacy.html
Правила работы с модулями
- Crate Root. При компиляции crate, компилятор ищет корень: src/lib.rs для библиотеки, либо src/main.rs для запускаемого файла (binary);
 - Модули. При декларировании модуля в crate root, например, 
mod test, компилятор будет искать его код в одном из мест:- Сразу после объявления в том же файле (inline);
 - В файле src/test.rs;
 - В файл src/test/mod.rs - старый стиль, поддерживается, но не рекомендуется.
 
 - Подмодули. В любом файле, кроме crate root, можно объявить подмодуль, например, 
mod automa. Компилятор будет искать код подмодуля в одном из мест:- Сразу после объявления в том же файле (inline);
 - В файле src/test/automa.rs;
 - В файле src/test/automa/mod.rs - *старый стиль, поддерживается, но не рекомендуется.
 
 - Путь до кода. Когда модуль часть crate, можно обращаться к его коду из любого места этой crate в соответствии с правилами privacy и указывая путь до кода. Например, путь до типа robot в подмодуле automa будет 
crate::test::automa::robot; - Private/public. Код модуля скрыт от родительских модулей по умолчанию. Для его публикации нужно объявлять его с 
pub modвместоmod; - Use. Ключевое слово 
useнужно для сокращения написания пути до кода:use crate::test::automa::robotпозволяет далее писать простоrobotдля обращения к данным этого типа. 
Note
Нужно лишь единожды внести внешний файл с помощью mod в дереве модулей, чтобы он стал частью проекта, и чтобы другие файлы могли на него ссылаться. В каждом файле с помощью mod не надо ссылаться, mod - это НЕ include из Python и других языков программирования.
Пример структуры
my_crate
├── Cargo.lock
├── Cargo.toml
└── src
    ├── test
    │   └── automa.rs
    ├── test.rs
    └── main.rsВложенные модули
Для примера, возьмём библиотеку, обеспечивающую работу ресторана. Ресторан делится на части front - обслуживание посетителей, и back - кухня, мойка, бухгалтерия.
mod front {
    mod hosting {
        fn add_to_waitlist() {}
        fn seat_at_table() {}
    }
    mod serving {
        fn take_order() {}
        fn serve_order() {}
        fn take_payment() {}
    }
}Пример обращения к функции вложенного модуля
Объявление модуля публичным с помощью pub не делает его функции публичными. Нужно  указывать публичность каждой функции по отдельности:
mod front_of_house {
    pub mod hosting { // модуль публичен, чтобы к нему обращаться
        pub fn add_to_waitlist() {} // функция явно публична
        // несмотря на публичность модуля, к функции обратиться нельзя
        // если она непублична
    }
}
pub fn eat_at_restaurant() {
    // Абсолютный путь через корень - ключевое слово crate
    crate::front_of_house::hosting::add_to_waitlist();
    // Относительный путь
    front_of_house::hosting::add_to_waitlist();
}Обращние к функции выше уровнем
Относительный вызов функции можно сделать через super (аналог “..” в файловой системе):
fn deliver_order() {}
mod back_of_house {
    fn fix_incorrect_order() {
        cook_order();
        super::deliver_order(); // вызов функции в родительском модуле
    }
    fn cook_order() {}
}Обращение к структурам и перечислениям
Поля структур приватны по умолчанию. Обозначение структуры публичной с pub не делает её поля публичными - каждое поле нужно делать публичным по отдельности.
mod back_of_house {
    pub struct Breakfast {      // структура обозначена как публичная
        pub toast: String,      // поле обозначено публичным
        seasonal_fruit: String, // поле осталось приватным
    }
    impl Breakfast {
        pub fn summer(toast: &str) -> Breakfast {
            Breakfast {
                toast: String::from(toast),
                seasonal_fruit: String::from("peaches"),
    } } } }
pub fn eat_at_restaurant() {
    // Обращение к функции. Без функции к структуре с приватным полем 
    // не получится обратиться:
    let mut meal = back_of_house::Breakfast::summer("Rye");
    // запись в публичное поле:
    meal.toast = String::from("Wheat");
    println!("I'd like {} toast please", meal.toast);
    // если раскомменировать строку далее, будет ошибка компиляции:
    // meal.seasonal_fruit = String::from("blueberries");
}Поля перечислений публичны по умолчанию. Достатоно сделать само перечисление публичным pub enum, чтобы видеть все его поля.
mod back_of_house {
    pub enum Appetizer { // обозначаем перечисление публичным
        Soup,
        Salad,
    } }
pub fn eat_at_restaurant() {
    let order1 = back_of_house::Appetizer::Soup;
    let order2 = back_of_house::Appetizer::Salad;
}Обращение к объектам под другим именем
С помощью as можно создать ярлык на объект в строке с use. Особенно это удобно в случае, когда нужно обратиться к одинаковым по имени объектам в разных модулях:
use std::fmt::Result;
use std::io::Result as IoResult; // IoResult - ярлык на тип Result в модуле io
fn function1() -> Result {
    // ... }
fn function2() -> IoResult<()> {
    // ... }
Ре-экспорт объектов
При обращении к объекту с помощью use, сам ярлык этот становится приватным - через него могут обращаться только функции текущего scope. Для того, чтобы из других модулей функции могли тоже обратиться через этот ярлык, нужно сделать его публичным:
mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    } }
pub use crate::front_of_house::hosting; // ре-экспорт объекта
pub fn eat_at_restaurant() {
    hosting::add_to_waitlist(); // обращение к функции через ярлык
}Работа с внешними библиотеками
Внешние библиотеки включаются в файл Cargo.toml. Далее, публичные объекты из них заносятся в scope с помощью use.
# Cargo.toml
rand = "0.8.5"use rand::Rng;
fn main() {
    let secret_number = rand::thread_rng().gen_range(1..=100);
}Если нужно внести несколько объектов из одной библиотеки, то можно сократить количество use:
//use std::cmp::Ordering;
//use std::io;
use std::{cmp::Ordering, io}; // список объектов от общего корня
//use std::io;
//use std::io::Write;
use std::io{self, Write}; // включение самого общего корня в scope
use std::collections::*; // включение всех публичных объектов по пути
Warning
Следует быть осторожным с оператором glob - *, так как про внесённые с его помощью объекты сложно сказать, где именно они были определены.