How to use module in another file besides main.rs - rust

I have 3 files in my src folder: 'main.rs', 'network.rs', and 'nodes.rs'. I would like to use a function I declared in nodes.rs in network.rs. I cannot seem to find a way to do this. All I can find online are ways to access the functions within main.rs.
main.rs:
mod network;
mod nodes;
fn main() {
network::run();
}
network.rs
pub fn run() {
newnode();
}
nodes.rs
pub fn newnode() {
println!("Test");
}

To access the nodes modules, you need to navigate back to main.rs and then descend to the submodule. You can do that by either starting from the root of the crate (main.rs in this example) with the crate keyword (so crate::nodes::newnode), or, because main.rs is the parent module of network, accessing it via super: super::nodes::newnode.

If you don't want to call the functions with the full path, you need to explicitly refer to them in the appropriate module with use.
At the beginning of network.rs: use super::nodes::newnode;.

Related

Is a direct function call and a self::function call always the same in rust?

Recently, I started to learn rust. I'm currently at section 7.4 (bringing paths into scope). Tried hard, but I can't understand the purpose of self::some_sort_of_identifier in rust. Would you please explain what is the difference between use self::module_name::function_name and use module_name::function_name? I tried both and they both worked as expected in the example below:
mod my_mod {
pub fn func() {
print!("I'm here!");
}
}
use my_mod::func;
fn main() {
func();
}
Running this program, as expected, I can see this statement printed into the terminal:
I'm here
And this program here gives me exactly the same results and the rust compiler doesn't complain about anything:
mod my_mod {
pub fn func() {
print!("I'm here!");
}
}
use self::my_mod::func;
fn main() {
func();
}
So, is self:: useless in rust? Why should I even use self::my_mod::my_function(); when I can directly call it like so: my_mod::my_function();.
Are there any cases in which they might defer?
For your use-case, it's mainly a relict from the 2015 rust edition.
In this edition the following code would not compile:
use my_mod::func;
mod my_mod {
use my_mod2::func2;
pub fn func() {
func2();
}
mod my_mod2 {
pub fn func2() {
print!("I'm here!");
}
}
}
fn main() {
func();
}
The compiler complains:
error[E0432]: unresolved import my_mod2
--> src\main.rs:4:9
|
| use my_mod2::func2;
| ^^^^^^^ help: a similar path exists: self::my_mod2
Why did it change? You can see the note about the path and module system changes here.
Rust 2018 simplifies and unifies path handling compared to Rust 2015. In Rust
2015, paths work differently in use declarations than they do
elsewhere. In particular, paths in use declarations would always start
from the crate root, while paths in other code implicitly started from
the current scope. Those differences didn't have any effect in the
top-level module, which meant that everything would seem
straightforward until working on a project large enough to have
submodules.
In Rust 2018, paths in use declarations and in other code work the
same way, both in the top-level module and in any submodule. You can
use a relative path from the current scope, a path starting from an
external crate name, or a path starting with crate, super, or self.
The blog post Anchored and Uniform Paths from the language team also underlines this
The uniformity is a really big advantage, and the specific feature we’re changing -
no longer having to use self:: - is something I know is a big
stumbling block for new users and a big annoyance for advanced users
(I’m always having to edit and recompile because I tried to import
from a submodule without using self).
The keyword itself however is still useful in use statments to refer to the current module in the path itself. Like
use std::io::{self, Read};
being the same as
use std::io;
use std::io::Read;

Add items to crate root module from separate files without creating child modules

I have a small Rust project, and would like the simplicity of a flat module system, combined with the modularity of separate files. In essence, I would like this program:
src/main.rs
fn print_hello_world() {
println!("Hello, world!");
}
fn main() {
print_hello_world();
}
to be structured akin to this:
src/print_hello_world.rs
pub fn print_hello_world() {
println!("Hello, world!");
}
src/main.rs
use crate::print_hello_world; // Error: no `print_hello_world` in the root
fn main() {
print_hello_world();
}
Note that there is only a single module in this pseudo project; the crate root module. No child modules exists. Is it possible to structure my project like this? If yes, how?
Solution attempts
It is easy to get this file structure by having this:
src/main.rs
mod print_hello_world;
use print_hello_world::print_hello_world;
fn main() {
print_hello_world();
}
but this does not give me the desired module structure since it introduces a child module.
I have tried finding the answer to this question myself by studying various authorative texts on this matter, most notably relevant parts of
The Rust Book
The Rust Reference
The rustc book
My conclusion so far is that what I am asking is not possible; that there is no way to use code from other files without introducing child modules. But there is always the hope that I am missing something.
This is possible, but unidiomatic and not recommended, since it results in bad code isolation. Making changes in one file is likely to introduce compilation errors in other files. If you still want to do it, you can use the include!() macro, like this:
src/main.rs
include!("print_hello_world.rs");
fn main() {
print_hello_world();
}

Rust: the usage of "self" when bringing paths into scope

mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
use self::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
hosting::add_to_waitlist();
hosting::add_to_waitlist();
}
The code is from Rust Book. In this case, if using the relative path, why bother to use self? I find that use front_of_house::hosting works well here.
So, any necessary reason to introduce self here?
The outcome of use front_of_house::hosting depends on the context. If the crate root contains extern crate front_of_house or front_of_house is a dependency in Cargo.toml, this will refer to hosting in that crate. In your case, however, there is the local module front_of_house, which takes priority over external crates. Conveniently, it's located just before the code that uses it, so it's obvious that it's the actual module being used. In larger files, however, there is a chance that the source of a module is ambiguous, i.e. if there is a dependency named the same as a local module. In that case, the extra self adds clarity to the code, helping you differentiate between dependencies and local modules. If, in that case, you wanted to use the dependency, you'd use ::front_of_house::hosting, which unconditionally refers to the dependency and fails if there isn't one named like that.

How to expose method to its sibling and parent only but not to client using that crate in rust [duplicate]

I have a crate that has lots of code, so I've split it into multiple files/modules. However, some modules have internal unsafe stuff (e.g. raw pointers) that I need to make public to the different modules, but I don't want to expose to users of my crate. How can I do that?
The only way I can think of is to actually have my crate just be one big module, but then there's no way to split it into different files, other than this solution which seems a bit hacky.
Normally when I come up against a real world problem that the simple examples in the Rust docs don't adequately explain I just copy a popular real world crate, e.g. git2-rs, but that just seems to effectively make everything public, including the raw pointers.
In order for an item to be exported from a library crate, there must be at least one path leading to it in which every component is public. This means that all you need to make an item public within your crate but not exported from the crate (I'll call this "internal" from now on, to mimic C# terminology) is to put it in a private module under the crate root.
However, that solution is quite restrictive. What if you'd like to have a module with exported functions and internal functions? In order to export some functions, we need to make the module public, and that mean all public items in that module will be exported as well.
Since Rust 1.18, there's a solution adapted to this kind of scenario: pub(restricted). This feature lets you specify "how public" an item should be. The syntax is pretty flexible (you can make an item visible to a particular module tree instead of the whole crate), but if you want to keep it simple, pub(crate) will make an item accessible anywhere within the crate, but not to other crates (equivalent to internal in C#).
For example, suppose we'd like to have a module util in which foo is exported (as mycrate::util::foo), bar is internal and baz is private to the module. The code might look like this:
pub mod util {
pub fn foo() {
unimplemented!()
}
pub(crate) fn bar() {
unimplemented!()
}
fn baz() {
unimplemented!()
}
}
If you're stuck on pre-1.18 Rust, there's a workaround, but it's a bit clunky. It involves defining all your items in private modules, and reexporting only those that you want to make public (with pub use) in public modules that only contain reexports. Here's what the example above would look like:
pub mod util {
pub use util_impl::foo;
}
mod util_impl {
pub fn foo() {
unimplemented!()
}
pub fn bar() {
unimplemented!()
}
fn baz() {
unimplemented!()
}
}
Not only is this not easy to read and understand, it doesn't cover all situations where pub can be used. For example, how would you make some fields of an exported struct accessible in other modules in the same crate without also exporting them? The only option would be to expose a wrapper with a single private field whose type is the struct that has public fields; that works fine if you want to hide all fields from other crates, but not if you want to expose some fields and make some other fields internal in the same struct.

How do I compile a multi-file crate in Rust?

I'm trying to figure out how to compile multi-file crates in Rust, but I keep getting a compile error.
I have the file I want to import into the crate thing.rs:
mod asdf {
pub enum stuff {
One,
Two,
Three
}
}
And my crate file test.rc:
mod thing;
use thing::asdf::*;
fn main(){
}
When I run rust build test.rc I get:
test.rc:3:0: 3:19 error: `use` and `extern mod` declarations must precede items
test.rc:3 use thing::asdf::*;
^~~~~~~~~~~~~~~~~~~
error: aborting due to previous error
There's obviously something simple about how modules, crates and use work that I'm just not getting. My understanding was that mod something; for files in the same directory or extern mod something; for libraries on the library path caused the object file to be linked. Then use would allow you to import parts of the module into the current file, function or module. This seems to work for stuff in the core library.
This is with version 0.6 of the rust compiler.
You just need to put the use at the top of the file:
use thing::asdf::*;
mod thing;
fn main() {}
This looks very strange, but
It's what the error message says (anything that you can put at the top level that is not use or extern mod is an "item", including mods), and
It's how Rust name resolution works. use is always relative to the top of the crate, and the whole crate is loaded before name resolution happens, so use thing::asdf::*; makes rustc look for thing as a submodule of the crate (which it finds), and then asdf as a submodule of that, etc.
To illustrate this last point better (and demonstrate the two special names in use, super and self, which import directly from the parent and current module respectively):
// crate.rs
pub mod foo {
// use bar::baz; // (an error, there is no bar at the top level)
use foo::bar::baz; // (fine)
// use self::bar::baz; // (also fine)
pub mod bar {
use super::qux; // equivalent to
// use foo::qux;
pub mod baz {}
}
pub mod qux {}
}
fn main() {}
(Also, tangentially, the .rc file extension no longer has any special meaning to any Rust tools (including in 0.6), and is deprecated, e.g. all the .rc files in the compiler source tree were recently renamed to .rs.)

Resources