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
Related
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 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::*;
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`
}
I have a small project which built with no issues when it was all in one big .rs file. I wanted to make it easier to work with, so I broke it up into modules, and the project is now structured like this:
├── GameState
│ ├── ballstate.rs
│ ├── collidable.rs
│ ├── gamestate.rs
│ ├── mod.rs
│ └── playerstate.rs
├── lib.rs
└── main.rs
In ballstate.rs, I need to use the rand crate. Here's an abbreviated version of the file:
extern crate rand;
pub struct BallState {
dir: Point,
frame: BoundingBox
}
impl BallState {
fn update_dir(&mut self) {
use rand::*;
let mut rng = rand::thread_rng();
self.dir.x = if rng.gen() { Direction::Forwards.as_float() } else { Direction::Backwards.as_float() };
self.dir.y = if rng.gen() { Direction::Forwards.as_float() } else { Direction::Backwards.as_float() };
}
}
However, when I run cargo build from the top level directory, I get the following error:
GameState/ballstate.rs:42:9: 42:13 error: unresolved import rand::*. Maybe a missing extern crate rand?
When I just had the extern crate declaration in my main.rs file, this worked. What's changed now that it's in a separate module?
To quote from the Crates and Modules chapter of the Rust book:
[...] use declarations are absolute paths, starting from your crate root. self makes that path relative to your current place in the hierarchy instead.
The compiler is correct; there is no such thing as rand, because you've put it inside a module, so the correct path to it would be GameState::ballstate::rand, or self::rand from within the GameState::ballstate module.
You need to either move extern crate rand; to the root module or use self::rand within the GameState::ballstate module.
You need to put the extern crate rand; line in you main.rs and/or lib.rs file. No need to put it in the other files.
Perhaps it is related to this bug.
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