I'm starting to learn Rust and I stumbled into a weird import problem. I have an example directory structure:
example_mod
file1.rs
example_mod.rs
file2.rs
I would like to import the contents of file2.rs into example_mod.rs. I tried:
use crate::file2;
use super::file2;
use file2;
And each time I get the use of undeclared type or module file2 error. How such sibling module should be imported?
Beginning new things is fun (and can be difficult). Now, your description of the problem you are having makes helping you kind of difficult. But, when you're starting out it can be hard to help yourself help-yourself. Check out how to create a MVCE.
Also check out what the Rust Book says about crates, modules, paths, and use. And, join the Rust Community if you want rust-specific help.
Okay, I'm making some assumptions about your code structure because you've left out a good deal of information.
So, if you run cargo new app you'll end up with a project folder containing a src/ directory.
I've added some files/directories and the result looks like this:
src/
├── core # a directory/folder
│ ├── mod.rs
│ └── some_other_code.rs # a "file"
├── main.rs
└── some_code.rs # another "file"
In main.rs:
/// Module declarations.
mod core;
mod some_code;
/// Bring paths into scope with the `use`
/// keyword keyword.
use self::some_code::hello;
// The above can also be written as:
// use some_code::hello;
// why?
/// An absolute path starts from a crate root by
/// using a crate name or a literal `crate`.
use crate::core::greeting;
const JUPITER: &str = "jupiter";
fn main() {
hello();
greeting();
// A relative path starts from the current
// module and uses self, super, or an identifier
// in the current module.
use self::another_mod;
// You can also check if the following would work:
// use crate::another_mod;
// Or even,
// use another_mod;
// why?
another_mod::jupiter();
}
mod another_mod {
use super::*;
pub fn jupiter() {
println!("hello, {}!", JUPITER);
}
}
In some_code.rs:
pub fn hello() {
println!("mars");
}
In core/mod.rs:
/// Module declaration.
pub mod some_other_code;
/// Re-exporting the greeting function.
pub use some_other_code::greeting;
In core/some_other_code.rs:
use crate::some_code;
pub fn greeting() {
println!("hello");
some_code::hello();
}
To give you an idea of what you'll find in the Rust Book:
Packages: A Cargo feature that lets you build, test, and share crates
Crates: A tree of modules that produces a library or executable
Modules and use: Let you control the organization, scope, and privacy of paths
Paths: A way of naming an item, such as a struct, function, or module
And,
src/main.rs and src/lib.rs are called crate roots. The reason for their name is that the contents of either of these two files form a module named crate at the root of the crate’s module structure, known as the module tree.
I've been through the book on this and ran that gamut. I personally don't like saying the following.
// *** main.rs
mod some_mod
use crate::some_mod::some_fn;
//rather just if you're going to
mod some_mod
use some_mod:some_fn;
//even further recall the binary name can see every mod that lives in main and lib
//so with the above you could move the mod to lib and keep main clean of mod
// *** lib.rs
pub mod some_mod
// then back in main just do
use rust_book::some_mod::some_fn;
// *** cargo.toml
[package]
name = "rust_book"
// Also keep in mind mods outside of lib will not be in cargo doc
Related
This question already has answers here:
How to use one module from another module in a Rust cargo project?
(3 answers)
Closed 10 days ago.
My Rust project structure inside src folder:
|main.rs
|routes folder:
|-mod.rs
|-route_func.rs
|blockchain folder:
|simple_func.rs
I got this error message: function exists but is inaccessible
How can I use the simple_func.rs functions inside the route_func.rs ?
It seems I need to construct a module tree...
Declare the new module in your main.rs file:
pub mod blockchain;
Declare your new module content inside the blockchain/mod.rs:
pub mod simple_func;
Declare the target function inside simple_func.rs
pub async fn target_func() -> {}
Import the target_func in the route_func.rs:
use crate::blockchain::simple_func::*;
Remember to add pub in all declarations and functions!
This is my directory structure
src/
├── lib.rs
├── pages/
│ ├── mod.rs
│ ├── home_page.rs
└── components/
├── mod.rs
└── header.rs
Inside my pages/home_page.rs I try to access my pub struct Header which is inside components/header.rs.
My components/mod.rs looks like this: pub mod header; which works fine because inside lib.rs - I can use it like:
mod components;
use components::header::Header;
However, I don't know how to access it in pages/homepage.rs. How can get access to that struct? Is it something in Cargo.toml?
You can use a whole bunch of Rust keywords to navigate between the modules of your crate:
super::components::Header
// `super` is like a `parent` of your current mod
crate::components::Header
// `crate` is like a root of you current crate
And to include submodules of current mod:
self::submodule1::MyStruct
// `self` is like current module
You can read more about that here
Also it is good idea to make a prelude mod of your crate and include all main items of your crate there, so then you can include them just by passing use crate::prelude::*.
You can read more about prelude in offical rust docs and here.
Inside my src/pages/home_page.rs I can use my header like: use crate::components::header::Header;
I started a new project in rust (it's my first project in rust, but my first programming language). I added a few functions, types and unit test in main.rs. Then I wanted to move it in two new files foo.rs and bar.rs.
How do I import/include/use bar.rs from foo.rs?
I already read:
https://doc.rust-lang.org/book/ch07-05-separating-modules-into-different-files.html
How do I do a basic import/include of a function from one module to another in Rust 2015?
Split a module across several files
How to include module from another file from the same project?
https://doc.rust-lang.org/stable/rust-by-example/mod.html
Neither have the following structure
src/
|-- main.rs
|-- foo.rs
|-- bar.rs
Where foo.rs is trying to use the content of bar.rs.
If I try to use a type Bar declared in bar.rs directly from foo.rs, I get:
error[E0433]: failed to resolve: use of undeclared type or module `Bar`
--> src/foo.rs
If I add mod bar at the beginning of foo.rs isn't any better:
error[E0583]: file not found for module `bar`
--> src/foo.rs
|
1 | mod bar;
| ^^^
|
= help: name the file either foo/bar.rs or foo/bar/mod.rs inside the directory "src"
And finally (but I wasn't expecting this one to work), with use bar; in foo.rs:
error[E0432]: unresolved import `bar`
--> src/foo.rs
|
1 | use bar;
| ^^^ no `grammar` external crate
I have a Rust project made by cargo init:
dir
|-src
|-main.rs
|-settings.rs
|-functions.rs
I have in settings.rs:
use ::functions;
but at compilation I get an error:
error[E0432]: unresolved import `functions`
--> src/settings.rs:3:5
|
3 | use ::functions;
| ^^^^^^^^^^^ no `functions` in the root
In your comments, you state:
I don't want to use [mod functions] because it will search for settings/functions.rs, and it is not i want to
Have you tried that? Assuming you've declared the module correctly ... this is exactly what you want.
main.rs:
mod functions;
mod settings;
fn main() {
...
}
settings.rs:
use functions;
pub fn something() {
functions::some_function_here();
}
If this does not work .. then there is something missing from your problem description.
It looks like you're confusing the role of the root namespace. use ::functions; means something slightly different than use functions;
Let's consider your project structure:
project
├── src
| ├── settings.rs
| ├── functions.rs
| └── main.rs
└── Cargo.toml
When you're within settings.rs, the other modules are at the same level, so a use functions; accesses the functions module.
If you do wish to refer to the functions module via the root namespace, then the full path looks like this ::project::functions and the use declaration is use ::project::functions;.
I'm following the Diesel examples guide, and my project looks exactly like this. I want to change it so that instead of running cargo run --bin publish_post 1, you use cargo run and are presented with a loop prompting you for what action you want to run.
I've moved everything out of bin/ and into the controllers/ directory. I want to reference this in main.rs as use controllers::post, so I have access to post::delete(), etc.
Once I move the files out of bin/, all the imports break. Likewise, I can't reference it from lib.rs.
Why do none of my imports work when the files are moved? How I could access the methods from these files?
I want a structure like this:
├── controllers
│ └── posts.rs
├── lib.rs
├── main.rs
├── models.rs
├── schema.rs
And within main.rs, I want to be able to do something like:
use controllers::posts;
pub fn main() {
// pseudocode
loop {
println!("what action would you like to perform?");
let ans = capture_input();
if ans == "insert" {
posts::insert();
} else if ans == "delete" {
posts::delete();
}
}
}
Making a folder doesn't automatically make a Rust submodule. You need to do two things:
Declare the module explicitly in the crate root (lib.rs or main.rs):
mod controllers;
Create controllers/mod.rs file and declare a submodule in it:
mod posts;