How to load sibling module file in Rust? [duplicate] - rust

This question already has an answer here:
How do I import from a sibling module?
(1 answer)
Closed 4 months ago.
everyone, here is my "models" module:
in mod.rs I do re-export:
mod distribution;
mod item;
mod project;
mod relation;
pub use distribution::Distribution;
pub use item::Item;
pub use project::Project;
pub use relation::Relation;
In main.rs Seem to work fine:
mod models;
use models::Item;
use models::Project;
use models::Relation;
use models::Distribution;
But how can I use Distribution inside Item (models/item.rs)?
I tried:
mod models;
use models::Distribution;
or
mod distribution;
use distribution::Distribution;
But compiler can't find relevant file.

While writing this question I found the answer, so let it be here:
// models/item.rs
use crate::models::Distribution;

Related

How do I keep a mod private and use it in another module within the same project in Rust?

So I want to have some modules defined in lib.rs but not make them public but only available for use within the project.
in my lib.rs, if I have the definition as this:
pub mod args;
in my main.rs, I can use the args modules this way:
use my_lib::args::Cli;
where my_lib is defined in Cargo.tml as
[lib]
name = "my_lib"
path = "src/lib.rs"
but I don't want pub mod args;. I tried changing to pub(crate) mod args; but this leads to compilation error that the args module cannot be found.
How do I make a module like args defined in lib.rs available without have to give it the most permissive visibility?
Since Rust separates the library lib.rs and binary main.rs into separate crates there is no simple way to include things that are in lib.rs and not pub from main.rs.
I suggest you follow the way of big crates (serde comes to mind) and add a pub mod __private; which conveys the meaning. You can additionaly annotate it with #[doc(hidden)] to hide it from the documentation making it even more obvious.

How to use structures from sibling/adjacent rust file?

I'm trying to edit a Rust project with the following structure:
src/iface/ip.rs
src/iface/tun.rs
I want to call things from ip.rs inside tun.rs. So on tun.rs I added:
use iface::ip;
but it says
unresolved import `iface::ip`
no `ip` in `iface`rustc(E0432)
This seems to be the way to do it as explained here https://stackoverflow.com/a/30687811/6655884 and here https://stackoverflow.com/a/26390046/6655884
I also tried mod ip but it didn't work either.
In iface/mod.rs
pub mod ip;
In iface/tun.rs
use crate::iface::ip;

use module inside module from src folder [duplicate]

This question already has answers here:
What are the valid path roots in the use keyword?
(2 answers)
Closed 4 years ago.
I want to separate the application logic to keep my main.rs file clean. I am using diesel for a simple project and I have the following files inside /src folder
main.rs
lib.rs
models.rs
schema.rs
I tried declaring the modules inside main.rs file and using them in the lib.rs file but that produces the following error:
unresolved import models; no models external crate [E0432]
main.rs looks like this:
pub mod lib;
pub mod schema;
pub mod models;
lib.rs produces error with this:
pub use models;
pub use schema::sent_sms;
I do not understand why things need to be so awfully complicated in this language, or maybe I am too stupid to understand it.
Please help me understand.
The main part of this answer was moved to the duplicate question!
So your problem is that use models; looks for models relative to the current module (lib). But models is not a sub module of lib, but of main. So the correct way to refer to these top level modules is like that:
use crate::{
models,
schema::sent_sms,
};
Additional notes:
If you have a executable project and just need a module to have some utility functions in, you usually wouldn't call it lib as that name is the default name for library crates' roots.
This use statement behavior changed with Rust 2018 (≥ 1.31))
Read this guide for more information about use statements and how they changed in Rust 2018

Why do I get "can't find crate" when using a module in Rust 2018?

I have a lib.rs file containing:
mod bindings {
// ...
}
pub use bindings::*;
What I get from rustc is:
| pub use bindings::*;
| ^^^^^^^^ can't find crate
Why does Rust think bindings is a crate instead of module?
You seem to be using the 2018 edition of Rust. There have been a few changes to paths in use declarations since the 2015 edition (aka Rust 1.0). The path after a use declaration now always needs to start with a crate name, the crate keyword denoting the root of the crate, self denoting the current module or super denoting the parent module. So either of these two use declarations should work:
pub use self::bindings::*;
or
pub use crate::bindings::*;

Can I include modules "sideways" in Rust?

I want to split a Rust program into multiple files, but the use of mod doesn't see to allow me to reference files in the same directory from files other than main.rs.
For example, if I have main.rs, game.rs, and matrix.rs in the same folder, I can reference structs/functions from game.rs or matrix.rs in main.rs with a mod game; or mod matrix;. I can't, however, reference matrix.rs from game.rs with a statement like mod matrix.
I've looked at several resources and all of them only have modules structures like trees that don't reference each other. Is it possible to use structs/functions from files in each other in Rust, or is that against the rules? If so, why doesn't Rust let you do that?
mod is module declaration. This directive declares a module and all of its contents. It just so happens that these contents may be located in another file. So this:
mod game;
mod matrix;
is roughly equivalent to this:
mod game {
// game.rs contents
}
mod matrix {
// matrix.rs contents
}
Naturally, since mod is a declaration of a module, you can't do it multiple times for the same module. That is, you can try and write something like
mod game {
mod matrix;
...
}
mod matrix;
but, as you can see, matrix and game::matrix are different modules, and naturally rustc requires different paths to their respective files, if they are external.
use, however, is import declaration. use declarations pull names from other modules for use in the current module. You can use any module and any public items from it any number of times from anywhere this module is accessible.
So, in order to reference matrix from game you need to use it:
// game.rs
use matrix;
Naturally, in order for this to work matrix should be declared with mod in the crate root.
As a side note, I personally think that the simplest way to understand Rust module system is to first forget that modules can be put in different files at all. That is, think as if a crate can only be defined in a single file. In Rust mod directives can have bodies and can nest, so nested mods actually define the module system of a crate:
mod foo {
mod bax {
...
}
mod baz {
...
}
}
mod bar {
mod qux {
mod zux {
...
}
}
}
If you only have a single file, you can easily see how mod and use directives would work, and relationship between modules should become clear.
And now you only need to add to the picture the fact that if a module is declared without a body, like in mod name;, its content is loaded either from name.rs or name/mod.rs, whatever is available. However, the full picture does not change in the slightest - these still are nested modules which can always be represented as a single source file with nested mod directives. In fact, cargo rustc -Z unstable-options --pretty=normal will print your crate in this form, after all modules in external source files are assembled into a single document. I suggest running this command on some crates with complex module structure to see how it looks in practice.

Resources