How to use structures from sibling/adjacent rust file? - rust

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;

Related

What's the proper way to import mods in other files in Rust?

I am writing a Rust project and I want to use multiple mods. The src directory has files:main.rs, default.rs, difficult.rs.
The default.rs has:
pub struct Info {...}
pub fn f(...) {...}
and adding mod default, I can directly use default::Info and default::f.
But I want to use Info in difficult.rs and I add mod default into difficult.rs, then it gets error which says that default is not found.
How should I fix this?
How should I fix this?
You might want to read the book? The solution is at section 7.4. Rust is not a language which is easy to learn, and learning rust by osmosis or random walking tends to be a frustrating and unsuccessful endeavour.
I would very strongly recommend reading the book cover to cover at least once.
Anyway use is how you "import" things into the local scope.
mod is how you declare a module. If you use mod multiple times for the same file, you're essentially creating copies of the modules, which the compiler will see as two unrelated modules with unrelated types.

Difference between "pub use" and "pub mod"?

Suppose I have this file hierarchy in a Rust package:
src/...
src/m1/mod.rs
src/m1/path/m2.rs
What would be the practical difference between having the line:
pub mod path::m2;
in my file m1/mod.rs, versus having the line:
pub use path::m2;
Trying to refresh my understanding of Rust after a time away, so this isn't my first learning cycle. (Of course, for other readers it may be.) I'm saying this because I'm not asking for a general explanation of the differences between use and mod. My unclarity is specific to the two directives above. It seems like they would both serve to make the module in file src/m1/path/m2.rs available to the module m1 and to anything else that imported it (because of the pub prefix on both directives). Is that right? Would these be perfect aliases, or would there be some differences? Is either idiom preferable to the other?
mod foo; is akin to copying and pasting a module into the current scope. That is, if the current scope can find module foo at its own "top level" — basically, if there's a file foo.rs or a folder foo in the same directory — then mod foo; basically gets transformed into mod foo { /* contents of foo */ }. Note that the syntax for mod requires that the thing after mod be an identifier, not an arbitrary path (so mod path::m2; would be illegal). I can only assume that modules that could be brought into scope aren't automatically brought into scope in order to limit the amount of work the compiler has to do when resolving names.
Meanwhile, once a container of items — whether that be a module, type, trait, etc — has been made available in the current scope, shortcuts to its items can be created with use path::to::item. If containers of items were ordinary variables, this would be akin to something like let item = path.to.item, if that were legal.
I'll edit this answer later to give a fuller explanation. But, with help from the comments and other answer posted here, plus some experimentation, I think I've come to a better understanding of these directives. There may be circumstances where one could use either pub use or pub mod, though they'd be contrived and in any case where both could work one should prefer the former (see third point below). The key differences are:
pub use is followed by a path (a bare identifier m2 would be the same as self::m2). pub mod is only followed by an identifier.
pub mod m2; in main.rs or lib.rs would include the contents of file ./m2.rs (or ./m2/mod.rs). If the line pub mod m2; is instead in a file path/m1.rs (or path/m1/mod.rs) then the included file would instead be path/m1/m2.rs (or path/m1/m2/mod.rs).
(You could include a module from another location using mod m2 { include!("path/m2.rs") } but this isn't idiomatic. I've also seen some attribute tricks that affect the location of the loaded module. But generally things work as described in the previous paragraph.)
The use directive doesn't request/order the compilation of any additional files. A mod directive is needed to do that.
(In fact the additional files aren't compiled separately, but merged into the source file where the mod directive occurs. Only the files that are crate roots (plus whatever is merged into them) get compiled.)
If one file in your crate had a pub mod m2; line, then another file could conceivably have a choice of also using pub mod or pub use. Subject to the constraints imposed by point 1 above.
But if you were in such circumstances, you wouldn't want to use the mod directive, as that would merge the relevant code into your source tree a second time. Perhaps the compiler might eventually undo the duplication, but what would you gain by hoping for that?
There's also this statement from the "Separating Modules into Different Files" chapter in the book:
Note that you only need to load the contents of a file using a mod declaration once somewhere in your module tree. Once the compiler knows the file is part of the project (and knows where in the module tree the code resides because of where you’ve put the mod statement), other files in your project should refer to the code in that file using a path to where it was declared...

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

"cargo check" gives dead code warning for function used only by test [duplicate]

I'm writing a program in Rust and I have some tests for it. I wrote a helper function for these tests, but whenever I build using cargo build it warns me that the function is never used:
warning: function is never used: ... #[warn(dead_code)] on by default
How I can mark this function as used so as not to get the warnings?
Specific question
How I can mark this function as used so as not to get the warnings?
The Rust compiler runs many lints to warn you about possible issues in your code and the dead_code lint is one of them. It can be very useful in pointing out mistakes when code is complete, but may also be a nuisance at earlier stages. Often, this can be solved by either deleting unused code, or by marking a public method. However, all lints can be turned off by allowing them, and your error message (#[warn(dead_code)] on by default) contains the name of the lint you could disable.
#[allow(dead_code)]
fn my_unused_function() {}
Alternative for testing
I wrote a helper function for these tests, but whenever I build using cargo build it warns me that the function is never used.
This happens to be a special case, which is that code that is only used for testing isn't needed in the real executable and should probably not be included.
In order to optionally disable compilation of test code, you can mark it accordingly using the cfg attribute with the test profile.
#[cfg(test)]
fn my_test_specific_function() {}
When marked in this way, the compiler knows to ignore the method during compilation. This is similar to commonly used ifdef usage in other languages like C or C++, where you are telling a preprocessor to ignore the enclosed code unless TESTING is defined.
#ifdef TESTING
...
#endif
For people getting this warning while making a rust library, you may get this if you don't have your modules set to pub in your lib.rs.
pub mod foo;
If something is only used in tests, it should be omitted altogether. This can be done with the #[cfg(test)] attribute.
dead_code is a lint, which means you can allow it on the thing that's causing it to trigger.
#[allow(dead_code)]
fn dummy() {}
fn main() {}
There is another situation where this can occur. If you have several helper functions in a module, e.g. in tests/utils/mod.rs and then several integration tests (tests/a.rs, tests/b.rs) each of which does
mod utils;
use utils::...;
then you will get dead code warnings if you do not use all of the code from all of the tests. For example if test a.rs only uses utils::foo and b.rs only uses utils::bar then you will get dead code warnings for both.
That is because each test is compiled as an independent crate. Here is the bug report for it. It looks difficult to solve so I wouldn't hold my breath.
You can disable specific lints for a whole project in Rust by going into your main.rs file and adding the following at the very top of the file:
#![allow(
dead_code,
unused_imports
)]
You max prefix the unused function name with an underscore:
fn _dummy() {}
fn main() {}
See: https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#dead-code
For some reason I found that setting the main function to public:
pub fn main()
and then copying my main.rs file to lib.rs
cp src/main.rs src/lib.rs
then recompiling fixed this.
No need to use a macro for it, although the macro should work for non main functions.

How to import everything from the crate root?

To import symbols from a module you either need to enumerate them or use a wildcard to import everything. That is, I can use either use module::{SomeSymbol, SomeOtherSymbol}; or use module::*;
However, when importing from the top-level module, the crate root, wildcards don't work. I can use either use {SomeSymbol, SomeOtherSymbol}; or use ::{SomeSymbol, SomeOtherSymbol}}; but neither use *; nor use ::*; work.
Why doesn't it work and how to import everything from the crate root?
As of Rust 1.14, use *; and use ::*; now work as intended (importing everything from the crate root)!
Useful links:
PR that introduced the syntax
Old issue about the lack of said syntax
My old answer in the edit log

Resources