DEV Community

Sven Kanoldt
Sven Kanoldt

Posted on • Edited on

little rust starter hint series: modules and imports

This post is additive to the awesome online book rust101 from Ralf Jung. Just in case things are a bit unclear be advised to read that book / section in addition then it should all make sense.

Today I want to show how you can separate your code in rust 2018 into several files and use pieces from here and there.

let's assume you have a normal rust project created by cargo that looks like:

tree . -L 2                                                                                                                                                              .
├── Cargo.lock
├── Cargo.toml
├── src
│   ├── main.rs
│   ├── part01.rs
│   ├── part02.rs
│   ├── part03.rs
│   ├── part04.rs
│   ├── part05.rs
│   └── part06.rs
Enter fullscreen mode Exit fullscreen mode

so you got that main.rs and a couple of other rust files. Those files can be called modules.

But, to be able to use a function or a data structure that is for instance defined in part05.rs from a different module like part06.rs the whole structure must be declared explicitly.

the easy way

in your main.rs you could just declare all the modules that you've got:

// main.rs

mod part01;
mod part02;
mod part03;
mod part04;
mod part05;
mod part06;

pub fn main() {
    part06::main();
}
Enter fullscreen mode Exit fullscreen mode

So that you can use for instance a data structure defined in module part05.rs in part06.rs

// part06.rs

use crate::part05::BigInt;      // <-- uses absolute imports
// or 
// use super::part05::BigInt;   // <-- uses relative imports
Enter fullscreen mode Exit fullscreen mode

Please note that BigInt has to be declared as a public structure with the keyword pub

// part05.rs

pub struct BigInt {
  pub data: Vec<u64>, // least significant digit first, no trailing zeros
}
Enter fullscreen mode Exit fullscreen mode

the hard way

Let's for now assume in your main.rs you've no explicit definitions about your module part05.rs:

// main.rs

mod part06;

pub fn main() {
    part06::main();
}

Enter fullscreen mode Exit fullscreen mode

now we get:

// part06.rs

use crate::part05::BigInt;

/* leads to the following error:

unresolved import `crate::part05`
part06.rs(2, 12): maybe a missing `extern crate part05;`?

 */
Enter fullscreen mode Exit fullscreen mode

as you can see the module part05 is not more known as of course we expected. So how can we fix that without promoting the module in main.rs, let's have a look at the #[path] directive:

// part06.rs

#[path = "part05.rs"]
mod part05;
use part05::BigInt;
Enter fullscreen mode Exit fullscreen mode

the #[path] directive tells the compiler to use the file part05.rs as a module called part05. So that we can now use it as a local import.

Note that the crate:: prefix is not more required, since we have declared the module here in that local scope only.

further reading

There is also further reading in the docs that will elaborate a bit more about the new convention for modules that got introduced in rust version 1.30.

Used versions:

$ rustc --version
rustc 1.37.0 (eae3437df 2019-08-13)
$ cargo --version
cargo 1.37.0 (9edd08916 2019-08-02)
Enter fullscreen mode Exit fullscreen mode

Thanks for reading and don't miss to give feedback :)

Top comments (6)

Collapse
 
bmitch profile image
Bill Mitchell

This is great! Do you plan on adding more types of posts like this that are additional information on the rust101 book?

Collapse
 
5422m4n profile image
Sven Kanoldt

Hi Bill,

thanks for the feedback. Well I thought about adding a few more yes. I guess one topic would be writing tests first and how to use a rspec like test "language" to make your test code speaking.

Do you have any wishes on topics that might be helpful to have covered?

Collapse
 
bmitch profile image
Bill Mitchell

Would love to see more on testing in Rust and also traits in Rust.

Thread Thread
 
5422m4n profile image
Sven Kanoldt

Well the traits are already very good covered in that book.
But maybe I will come across some simplification thoughts that helps to grasp the essence even faster, then I'll write about it.

Thread Thread
 
bmitch profile image
Bill Mitchell

Sounds great!

Thread Thread
 
5422m4n profile image
Sven Kanoldt

Hey Bill, you can now checkout the latest post in the series about tests

Hope you have fun with it.

Cheers