Rust import error - rust

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;.

Related

Is it possible to have a private module named `lib` if I specify a separate lib target in Cargo.toml?

I have a binary application I'm developing in Rust with a lib directory of helpers, and I want to know how to export helper functions for integration testing—e.g.
src
|- data_access_layer.rs
|- main.rs
|- lib
|- util.rs
When I tried to export data_access_layer helpers for integration testing I added a [lib] configuration to my Cargo.toml pointing at test_lib.rs
// test_lib.rs
pub mod data_access_layer;
with a file structure that now looks like this:
src
|- data_access_layer.rs
|- main.rs
|- lib
|- util.rs
|- test_lib.rs
...but when I try to run (or test) my application now, I get errors like "could not find lib in the crate root"
Here's my Cargo.toml file.
[package]
name = "api-service"
version = "0.11.14"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
diesel = { version = "2", features = ["mysql", "extras", "chrono", "r2d2"] }
[dev-dependencies]
pretty_assertions = "1.2.1"
[lib]
name = "test_lib"
path = "src/test_lib.rs"
What would you advise in this situation? Is it just a bad idea to store my own helpers under a collision file name like this? I would expect my TOML config to free up the word lib for use...
I assume you still want to use stuff in src/lib/utils.rs in wich case you still need to create either src/lib.rs or src/lib/mod.rs with the following content:
// either src/lib.rs or src/lib/mod.rs
pub mod utils;
That being said it's still a bad idea to use the name lib for some internal module and add a custom [lib] section cause it will confuse other people looking at the code, thus it should only be done with a good reason to do so.

Rust - Include rust module in another directory

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;

How to include file from another file in the same directory of the same project?

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

Rust - importing root file to a module

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

Move Diesel methods into other directories

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;

Resources