191
votes

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?

3

3 Answers

303
votes

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!");
}
54
votes

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()`");
}
25
votes

I really like Gardener's response. I've been using the suggestion for my module declarations. Someone please chime in if there is a technical issue with this.

./src
├── main.rs
├── other_utils
│   └── other_thing.rs
└── utils
    └── thing.rs

main.rs

#[path = "utils/thing.rs"] mod thing;
#[path = "other_utils/other_thing.rs"] mod other_thing;

fn main() {
  thing::foo();
  other_thing::bar();
}

utils/thing.rs

pub fn foo() {
  println!("foo");
}

other_utils/other_thing.rs

#[path = "../utils/thing.rs"] mod thing;

pub fn bar() {
  println!("bar");
  thing::foo();
}