How to use multiple files in rust? - rust

How to use multiple files in rust?
My main code is in file1.rs. file2.rs runs the main function of file1.rs multiple times, that's why I want to split it into 2 files, to keep my code clean. Than I just want to run the main function of file2.rs in my main.rs file. (I'm using the latest version of rust - 2021)
Folder structure:
├── Cargo.lock
├── Cargo.toml
├── src
│ ├── main.rs
│ └── file1.rs
| └── file2.rs
└── target
main.rs
pub mod file1;
pub mod file2;
pub fn main() {
file2::main();
}
file2.rs
pub mod file1;
pub fn main() {
file1::func("Bob");
file1::func("Alice");
}
file1.rs
pub fn func(name: &str) {
println!("Hello {}", name.to_string());
}
I get this error message:
file not found for module `file1`
to create the module `file1`, create file "src/file2/file1.rs"
or "src/file2/file1/mod.rs" rustcE0583

Here you are saying that file2.rs has a module called file1, so your tree should be:
src
|
---- main.rs
---- file2.rs
---- file2
|
----- file1.rs
Or change it to:
main.rs:
pub mod file1;
pub mod file2;
// ...
file2.rs:
// pub mod file1
// ...

You need to make the main functions public using pub fn main() {...}. Also, the syntax you used to call the file1::main is invalid, you would have to provide actual values like 1 and "foo".

You can import from other modules (files) in the same directory:
use super::file2::*;

Related

How to use rust module inside a different test directory?

This is my directory structure,
.
├── Cargo.lock
├── Cargo.toml
├── src
│ ├── add.rs
│ └── main.rs
└── tests
└── add_test.rs
add.rs
pub fn add(a: u8, b: u8) -> u8 {
return a + b;
}
main.rs
pub mod add;
fn main() {}
add_test.rs
#[cfg(test)]
mod tests {
#[test]
fn add_test() {
// how do I use add.rs module?
}
}
In add_test function how do I test add.rs's add function?
Notice that you are using mod add;. This is not a public module meaning it is unavailable outside of your crate.
To have it available outside the crate (and therefore available in the test) you can either make the module public, or reexport the function itself.
Additionally, to do this, you will need a lib.rs file in src where the exports are put:
// Make module public
pub mod add;
// Make the function available at the root of the crate
pub use add::add;
To then use your function in tests, you call it the same way you would call a function for a different crate. Lets assume your crate was named your-crate:
// If your module is public
your-crate::add::add(2,3);
// If you reexport the function
your-crate::add(2,3);
See more details in the chapter on test organization in the Rust book.

how to include a module from another file [duplicate]

This question already has answers here:
How can I include a module from another file from the same project?
(6 answers)
Closed 1 year ago.
I created a Cargo project. My project tree looks like this:
├── src
├── main.rs
├── animal.rs
└── human.rs
animal.rs
use crate::human::Job;
pub struct Animal {
id: u8,
job: Job,
}
impl Animal {
pub fn new(i: u8, j: Job) -> Animal {
Animal {id:i, job:j}
}
}
human.rs
pub struct Human {
id: u8,
job: Job,
}
pub enum Job {
Builder,
Magician,
}
impl Human {
pub fn new(i: u8, j: Job) -> Human {
Human {id: i, job: j}
}
}
When I compile it, it complains
$ cargo run
error[E0433]: failed to resolve: could not find `human` in the crate root
--> src/animal.rs:4:17
|
4 | job: crate::human::Job,
| ^^^^^ could not find `human` in the crate root
It gets compiled if I add "mod human;" in main.rs. What is the right way to include one module from another file in the same project?
The default package structure cargo expects is described here: https://doc.rust-lang.org/cargo/guide/project-layout.html
Therefore, you would expect to have the following files:
└── src
├── main.rs
├── lib.rs
├── animal.rs
└── human.rs
And lib.rs should contain
mod animal;
mod human;
The main.rs is an executable that would use the crate as if the library was a dependency:
use <crate_name>::human::Job;
fn main() {
// do whatever with `Job`
}
crate_name here would be the name of the crate in Cargo.toml.
Although technically nothing prevents you from declaring the modules inside main.rs like so:
mod animal;
mod human;
fn main() {
// use `human::Job`
}

How to import a function from another folder in the folder above

My directory structure looks like this
src
├── main.rs
├── paas_core
│   ├── create.rs
│   └── mod.rs
└── rest_api
├── mod.rs
└── rest.rs
I want to use a function declared in file create.rs in the file called rest.rs. I am trying to use the module in the rest_api module but I can not figure out how to do it.
I tried using super::paas_core in rest.rs but that didn't work.
In the file rest_api/rest.rs do you have to use use crate::paas_core; in order to be able to reference from rest_api to paas_core and paas_core/mod.rs need the statement pub mod create; to ensure you can call the function from rest_api directly using paas_core::create::create_func();
I hope it explains it. An full example might look like this:
file: main.rs
mod paas_core;
mod rest_api;
fn main() {
rest_api::rest_func();
}
file: rest_api/mod.rs
mod rest;
pub fn rest_func() {
println!("rest_func() in rest_api/mod.rs called!");
rest::rest_caller();
}
file: rest_api/rest.rs
use crate::paas_core;
pub fn rest_caller() {
println!("rest_caller() in rest_api/rest.rs called!");
paas_core::create::create_func();
}
file: paas_core/mod.rs
pub mod create;
file: paas_core/create.rs
pub fn create_func() {
println!("create_func() in paas_core/create.rs finally called!");
}
output if you are running it:
rest_func() in rest_api/mod.rs called!
rest_caller() in rest_api/rest.rs called!
create_func() in paas_core/create.rs finally called!

How Rust finds its dependencies [duplicate]

By following this guide I created a Cargo project.
src/main.rs
fn main() {
hello::print_hello();
}
mod hello {
pub fn print_hello() {
println!("Hello, world!");
}
}
which I run using
cargo build && cargo run
and it compiles without errors. Now I'm trying to split the main module in two but cannot figure out how to include a module from another file.
My project tree looks like this
├── src
├── hello.rs
└── main.rs
and the content of the files:
src/main.rs
use hello;
fn main() {
hello::print_hello();
}
src/hello.rs
mod hello {
pub fn print_hello() {
println!("Hello, world!");
}
}
When I compile it with cargo build I get
error[E0432]: unresolved import `hello`
--> src/main.rs:1:5
|
1 | use hello;
| ^^^^^ no `hello` external crate
I tried to follow the compiler's suggestions and modified main.rs to:
#![feature(globs)]
extern crate hello;
use hello::*;
fn main() {
hello::print_hello();
}
But this still doesn't help much, now I get this:
error[E0463]: can't find crate for `hello`
--> src/main.rs:3:1
|
3 | extern crate hello;
| ^^^^^^^^^^^^^^^^^^^ can't find crate
Is there a trivial example of how to include one module from the current project into the project's main file?
You don't need the mod hello in your hello.rs file. Code in any file but the crate root (main.rs for executables, lib.rs for libraries) is automatically namespaced in a module.
To include the code from hello.rs in your main.rs, use mod hello;. It gets expanded to the code that is in hello.rs (exactly as you had before). Your file structure continues the same, and your code needs to be slightly changed:
main.rs:
mod hello;
fn main() {
hello::print_hello();
}
hello.rs:
pub fn print_hello() {
println!("Hello, world!");
}
If you wish to have nested modules...
Rust 2018
It's no longer required to have the file mod.rs (although it is still supported). The idiomatic alternative is to name the file the name of the module:
$ tree src
src
├── main.rs
├── my
│   ├── inaccessible.rs
│   └── nested.rs
└── my.rs
main.rs
mod my;
fn main() {
my::function();
}
my.rs
pub mod nested; // if you need to include other modules
pub fn function() {
println!("called `my::function()`");
}
Rust 2015
You need to put a mod.rs file inside your folder of the same name as your module. Rust by Example explains it better.
$ tree src
src
├── main.rs
└── my
├── inaccessible.rs
├── mod.rs
└── nested.rs
main.rs
mod my;
fn main() {
my::function();
}
mod.rs
pub mod nested; // if you need to include other modules
pub fn function() {
println!("called `my::function()`");
}
I really like Gardener's response. I've been using the suggestion for my module declarations.
./src
├── main.rs
├── other_utils
│ └── other_thing.rs
└── utils
└── thing.rs
File main.rs
#[path = "utils/thing.rs"] mod thing;
#[path = "other_utils/other_thing.rs"] mod other_thing;
fn main() {
thing::foo();
other_thing::bar();
}
File utils/thing.rs
pub fn foo() {
println!("foo");
}
File other_utils/other_thing.rs
#[path = "../utils/thing.rs"] mod thing;
pub fn bar() {
println!("bar");
thing::foo();
}
In a non main.rs (or lib.rs) file if you want to include from a file in the same directory then the code below works. The key is to use the word super:: for the include. (This is how I rewrote the answer of rodo without using path.)
Directory tree:
src
├── main.rs
├── my.rs
└── my
├── a.rs
└── b.rs
To include a.rs in b.rs:
File src/my/a.rs
pub fn function() {
println!("src/my/a.rs/function()");
}
File src/my/b.rs
use super::b::function;
fn f2() {
function();
}
File src/my.rs
mod a;
mod b;
File src/main.rs
mod my;
As of 2022
├── src
├── main.rs
├── scripts
│ └── func.rs
└── scripts.rs
If I want to call the functions from the func.rs file (which are inside the scripts folder), I created a so-called "linking" file in the root directory the same as the folder's name (it's not necessary to have the linking file name and the folder name the same).
Content of file scripts/func.rs:
pub fn sayHello(){
println!("Hello, World!");
}
In the scripts.rs file I have:
pub(crate) mod func;
Then in my main.rs file I have called the sayHello() function as below:
mod scripts;
fn main() {
scripts::func::sayHello();
}
its a faily simple approach in solving this, you need to add mod into the main.rs file, for its to be accessible throughout the file tree

How can I include a module from another file from the same project?

By following this guide I created a Cargo project.
src/main.rs
fn main() {
hello::print_hello();
}
mod hello {
pub fn print_hello() {
println!("Hello, world!");
}
}
which I run using
cargo build && cargo run
and it compiles without errors. Now I'm trying to split the main module in two but cannot figure out how to include a module from another file.
My project tree looks like this
├── src
├── hello.rs
└── main.rs
and the content of the files:
src/main.rs
use hello;
fn main() {
hello::print_hello();
}
src/hello.rs
mod hello {
pub fn print_hello() {
println!("Hello, world!");
}
}
When I compile it with cargo build I get
error[E0432]: unresolved import `hello`
--> src/main.rs:1:5
|
1 | use hello;
| ^^^^^ no `hello` external crate
I tried to follow the compiler's suggestions and modified main.rs to:
#![feature(globs)]
extern crate hello;
use hello::*;
fn main() {
hello::print_hello();
}
But this still doesn't help much, now I get this:
error[E0463]: can't find crate for `hello`
--> src/main.rs:3:1
|
3 | extern crate hello;
| ^^^^^^^^^^^^^^^^^^^ can't find crate
Is there a trivial example of how to include one module from the current project into the project's main file?
You don't need the mod hello in your hello.rs file. Code in any file but the crate root (main.rs for executables, lib.rs for libraries) is automatically namespaced in a module.
To include the code from hello.rs in your main.rs, use mod hello;. It gets expanded to the code that is in hello.rs (exactly as you had before). Your file structure continues the same, and your code needs to be slightly changed:
main.rs:
mod hello;
fn main() {
hello::print_hello();
}
hello.rs:
pub fn print_hello() {
println!("Hello, world!");
}
If you wish to have nested modules...
Rust 2018
It's no longer required to have the file mod.rs (although it is still supported). The idiomatic alternative is to name the file the name of the module:
$ tree src
src
├── main.rs
├── my
│   ├── inaccessible.rs
│   └── nested.rs
└── my.rs
main.rs
mod my;
fn main() {
my::function();
}
my.rs
pub mod nested; // if you need to include other modules
pub fn function() {
println!("called `my::function()`");
}
Rust 2015
You need to put a mod.rs file inside your folder of the same name as your module. Rust by Example explains it better.
$ tree src
src
├── main.rs
└── my
├── inaccessible.rs
├── mod.rs
└── nested.rs
main.rs
mod my;
fn main() {
my::function();
}
mod.rs
pub mod nested; // if you need to include other modules
pub fn function() {
println!("called `my::function()`");
}
I really like Gardener's response. I've been using the suggestion for my module declarations.
./src
├── main.rs
├── other_utils
│ └── other_thing.rs
└── utils
└── thing.rs
File main.rs
#[path = "utils/thing.rs"] mod thing;
#[path = "other_utils/other_thing.rs"] mod other_thing;
fn main() {
thing::foo();
other_thing::bar();
}
File utils/thing.rs
pub fn foo() {
println!("foo");
}
File other_utils/other_thing.rs
#[path = "../utils/thing.rs"] mod thing;
pub fn bar() {
println!("bar");
thing::foo();
}
In a non main.rs (or lib.rs) file if you want to include from a file in the same directory then the code below works. The key is to use the word super:: for the include. (This is how I rewrote the answer of rodo without using path.)
Directory tree:
src
├── main.rs
├── my.rs
└── my
├── a.rs
└── b.rs
To include a.rs in b.rs:
File src/my/a.rs
pub fn function() {
println!("src/my/a.rs/function()");
}
File src/my/b.rs
use super::b::function;
fn f2() {
function();
}
File src/my.rs
mod a;
mod b;
File src/main.rs
mod my;
As of 2022
├── src
├── main.rs
├── scripts
│ └── func.rs
└── scripts.rs
If I want to call the functions from the func.rs file (which are inside the scripts folder), I created a so-called "linking" file in the root directory the same as the folder's name (it's not necessary to have the linking file name and the folder name the same).
Content of file scripts/func.rs:
pub fn sayHello(){
println!("Hello, World!");
}
In the scripts.rs file I have:
pub(crate) mod func;
Then in my main.rs file I have called the sayHello() function as below:
mod scripts;
fn main() {
scripts::func::sayHello();
}
its a faily simple approach in solving this, you need to add mod into the main.rs file, for its to be accessible throughout the file tree

Resources