7

Let's say that I have this file structure in my project:

.
├── Cargo.lock
├── Cargo.toml
├── src
│   ├── hotel
│   │   ├── guest.rs
│   │   ├── hotel_manager.rs
│   │   └── hotel.rs
│   ├── lib.rs
│   └── main.rs

In hotel_menager I declared only that I will use hotel and guest module:

pub mod hotel;
pub mod guest;

Then inside lib.rs I declared that I will use hotel_manager module:

pub mod hotel_manager;

and in the end I wanted to use hotel and guest in my main.rs binary but I am getting this error :

file not found for module hotel_manager

Then I thought that maybe I should use use but it also didn't help at all:

use crate::hotel::hotel_manager;

unresolved import crate::hotel.

My Cargo.toml:

[package]
name = "learn_file_spliting"
version = "0.1.0"
authors = ["kaczor6418 <[email protected]>"]
edition = "2018"

[lib]
name = "lib"
path = "src/lib.rs"

[[bin]]
name = "main"
path = "src/main.rs"

How can I use this nested module in lib.rs and then use re-exported modules inside main.rs ?

I know that if I create hotel_manager in /src directory then everything will work, but I want to have this hotel_manager module inside nested directory and learn how to use nested modules.

1
  • mod hotel_manager; will look for ./hotel_manager.rs or ./hotel_manager/mod.rs, but not for ./hotel/hotel_manager.rs. Commented Sep 6, 2020 at 16:51

1 Answer 1

14

In Rust, you can't create a module by simply having it exist in the directory tree. You have to explicitly declare it with mod module_name; statement. This doesn't only declare that a module named module_name is used, it declares that such a module exists at all.

pub mod hotel_manager; doesn't work in src/lib.rs because this tries to creates a submodule named hotel_manager in the crate's root module, which would have to exist in either src/hotel_manager.rs or src/hotel_manager/mod.rs -- and neither exist.

Importing crate::hotel::hotel_manager in src/lib.rs doesn't work because you have never declared a pub mod hotel; in src/lib.rs, and therefore, no module named crate::hotel exists at this point.

Basically, for the hotel_manager module to exist at src/hotel/hotel_manager.rs, it would have to be declared as a submodule of the a crate::hotel module, which itself would need to be declared in the root module.

The way to do what you want is to write the following in src/lib.rs:

pub mod hotel;

This submodule named hotel would have to exist at either src/hotel.rs or src/hotel/mod.rs. Since we want it to have further submodules, by convention, the latter is used. So create a file named src/hotel/mod.rs, with the following contents:

pub mod guest;
pub mod hotel_manager;
pub mod hotel;

This creates a proper module structure we want with hotel as a submodule of the root module, which contains further submodules named guest, hotel_manager and hotel.

Then, in the crate::hotel::hotel_manager module, instead of using mod statements, you should use the following statements, which import the modules that have been declared elsewhere into the current scope:

use crate::hotel::guest;
use crate::hotel::hotel;

Note that in Rust, you can import items smaller than just the whole module. For example, if you have a struct named Hotel in the crate::hotel::hotel module, you can import only that with a statement like use crate::hotel::hotel::Hotel;

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.