Importing module from another module

I'm trying to import content of the module from file in the same directory ( /src ) in current module but I'm always getting an error that module can't be found.

   Compiling rox v0.1.0 (file:///Users/apple/Development/rox)
error[E0583]: file not found for module `player`
  --> src/table.rs:54:5
   |
54 | mod player;
   |     ^^^^^^
   |
   = help: name the file either table/player.rs or table/player/mod.rs inside the directory "src"

Shouldn't I be able to import module in this way when it's in the same directory?

mod does not import modules, it declares them. You use them like anything else. Think about it like this: you don't write struct Blah; every time you want to "import" a struct type, you use path::to::Blah;.

There's more about modules in the book.

1 Like

But why do I write mod in a main file then to use content in them if it's only for declaration?

Thanks, I know about use but now I realized I should import things one by one. However, when I try to write use in main.rs I get the error about unresolved import.

1 Like

I'm not sure what you mean by this. You write mod to declare that a module exists within a containing module, then you can write use to access stuff from it from anywhere (visibility rules permitting).

1 Like

No, I don't need use after I do mod player; in the main.rs (from that point I can do player::(something...). I only need use when I import things from other modules in current module. I have use to import io from standard library.

Right, but that's because player is right there. Same way you don't need to use a struct you've defined in the current module.

Modules aren't special; they're handled just like everything else.

I don't quite understand this:

All files are in the same directory (/src) so I don't understand why I need different approach if everything is handled in the same way.

This is how it looks now:

table.rs

use player::Player;
use player::PlayerKind;

main.rs

mod player;
mod table;

The code in main.rs is declaring that those modules exist, and that they exist within the main module. It's describing a tree of modules, like a tree of folders and files.

The code in table.rs is in the same directory, but it's in a different module, so you need to specifically say that you're referring to the contents of the player module in the main module.

Think of it like a filesystem. The main module (main.rs or lib.rs) is the root directory. mod player; and mod table; are declaring that subdirectories called player and table exist. When you're writing code in table.rs, that's like being in the /table directory; if you want to refer to the contents of /player, you need to specify that. use player::Player; is like doing ln -s /player/Player Player to make a link to the /player/Player file available in the current directory.

2 Likes

Thanks, it's crystal clear now!

Also, as an addendum: extern crate thingy; is kind-of sort-of like doing: mkdir thingy; mount /dev/crates/thingy $PWD/thingy. That is, it attaches the external crate to your module tree as if you'd declared the root module of that crate right there with that name.

Aside from the whole visibility thing, you can very nearly map the Rust module system directly to the UNIX VFS.

1 Like

mod is like struct or fn. You declare your structs/functions once, in one place, and then use them everywhere else. Same applies to making modules with mod.

1 Like