Understand packages, crates and path

├── Cargo.lock
├── Cargo.toml
├── src/
│   ├── lib.rs
│   ├── main.rs
│   ├── some_dir
│     ├──  some_file.rs

Assume in some_file.rs we have:

pub fn foo() { // ... }

How can I call this function in lib.rs?

For that example, you could specify the module file path explicitly when declaring the module in lib.rs:

#[path = "some_dir/some_file.rs"]
mod some_mod;

pub fn run() {
    some_mod::foo();
}
1 Like

#[path] is unnecessary if the directory structure mimics the intended module structure:

mod some_dir {
    pub mod some_file; // must be `pub` to be visible outside this module
}

// how you call it:
some_dir::some_file::foo();
1 Like

Have a look at my cheat sheet:

2 Likes

I understand the hierarchy, but the difficulty I find in cargo is how to call functions of different files, 'import' modules of other files and use them, in other words, how the files interact with each other in hierarchy. Thanks anyways.

Start by thinking about this not as "calling functions of different files" but "calling functions of different modules".

Again, you import (use) modules, not files. The tree of modules is defined by the file hierarchy and "filtered" by the mod statements.

2 Likes

Don't know if this will help or not, but there seem to be 2 things about the module system that tend to trip people up when coming to Rust from other languages:

  1. There is a file hierarchy and a module hierarchy. Both can be any shape you want, but things will usually be easiest for you if they are the same shape.

  2. To use a path, each element of the path has to be visible to the current module.

1 Like

I agree.

I disagree with both points. :slight_smile:

They cannot be any shape you want. Without using the obscure #[path] directive, which IIRC isn't even mentioned in the Book, the path hierarchy has to follow the module hierarchy according to very specific rules.

And what complicates it a bit, these rules are more than "they have to be the same shape", as you can see from my cheat sheet.

#[path] is part of what I'm talking about when I say "any shape you want", yes. (Along with being able to specify the crate root in Cargo.toml.) It's not mentioned in the book, but everybody seems to know about it anyway, so I wouldn't call it "obscure". Of all the people who post in here confused about modules, probably 75% of them¹ already know about it and have used it to further confuse themselves.

¹ Incidentally, this is the same as the fraction of statistics that are made up on the spot.

1 Like

Exactly, I think there's some selection bias going on here... those who know about [#path] are confused about the module system, or vice versa.