'How do I "use" or import a local Rust file? [duplicate]

How do I include a file with the full path my_project/src/include_me.rs in main.rs?

I've checked the dependencies guide, and all of them appear to be including a binary. I've also checked "The Book", but none of the examples there end in ".rs" either.

How do I make include_me.rs compile with the rest of the project?



Solution 1:[1]

There are basically two (main) ways in Rust to include code from somewhere else:

1. "Including" internal code

If your include_me.rs belongs to your project, you should move it to the same folder main.rs lies in:

??? src
    ??? include_me.rs
    ??? main.rs

Then you can write this in your main.rs:

mod include_me;

fn main() {
    // Call a function defined in the other file (module)
    include_me::some_function();
}

A mod declaration makes the Rust compiler look for the corresponding .rs files automatically!

So everything that belongs to your project, belongs in the same folder (or a subfolder thereof) as the folder where main.rs (or lib.rs) is lying. The files are then "included" via the module system. To read a good introduction into modules, please read the chapter on modules in the Rust book. You could also check out Rust by Example on that topic. The module system is pretty central and thus important to learning Rust.

2. "Including" external code

If your include_me.rs is something that doesn't belong to your actual project, but is rather a collection of useful things you are using in multiple projects, it should be seen as a library. To include code of such external libraries, you have to include it as an extern crate. And to make your life easier, you really want to use Cargo!

So let's prepare your include_me.rs as Cargo library project. You need the following file structure (which is automatically generated by cargo new my_library --lib):

. my_library
  ??? Cargo.toml
  ??? src
      ??? lib.rs

Now copy all the contents from include_me.rs into lib.rs (it is just convention to call the root file of a library project lib.rs). Let's say that the my_library folder's full path is ~/code/my_library.

Now let's prepare your main project's Cargo project. It has a similar file structure (but a main.rs instead of lib.rs, because it's a executable-project, not a library-project):

. my_project
??? Cargo.toml
??? src
    ??? main.rs

To declare your dependency on my_library, you have to put this into your Cargo.toml:

[package]
name = "my_project"
version = "0.1.0"
authors = ["you"]
edition = "2018"

[dependencies]
my_library = { path = "~/code/my_library" }

You can also use relative paths ("../my_library"), but it only makes sense if you know that the two projects always stay where they are, relative to one another (like if they are both managed in the same repository).

Now you can, in your main.rs, write:

use my_library::some_function();

fn main() {
    // Call a function defined in the other file (extern crate)
    some_function();
}

If you want to upload any of those two projects, you have to interact with crates.io (or another crates registry, if your company has one), but this is another topic.

(Note: some time ago, it was necessary to write extern crate my_library; inside main.rs. This is not necessary anymore, but you might find old code with extern crate declarations.)

Any other ways?

Yes, but you shouldn't use those. There is the include!() macro which allows you to verbatim include other files, just like the #include from C-land. However, it is strongly discouraged to use this in situations where the module system would be able to solve your problem. include!() is only useful in very special situations, often linked to a more complex build system which generates code.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1