How to have multiple files with one module?

You cannot.

You can have more modules than files (the typical examples being mod tests nested in the file), but not the reverse.


However, this does not matter because you can use encapsulation + re-export.

The default when declaring a submodule with mod xxx; is that xxx is private: no user of the current module will know that it depends on xxx.

Combine this with selecting re-exporting symbols:

pub use self::leg::walk;
pub use self::head::nose::smell;
pub use self::tail::iron_tail;
pub use self::mouth::sonic_bark;

And you can call those directly: dog::walk(), dog::smell(), ...

Therefore, private imports and public re-exports help you have a hidden internal hierarchy while exposing a flat public interface.


Complete example:

mod dog {
    pub use self::head::nose::smell;
    pub use self::leg::walk;
    pub use self::mouth::sonic_bark;
    pub use self::tail::iron_tail;

    mod leg {
        pub fn walk() {}
    }

    mod head {
        pub mod nose {
            pub fn smell() {}
        }
    }

    mod tail {
        pub fn iron_tail() {}
    }

    mod mouth {
        pub fn sonic_bark() {}
    }
}

fn main() {
    dog::sonic_bark();
}

It is possible, but you should absolutely not do this because it's unidiomatic, will probably break various tools and IDEs, and is just generally confusing. Please don't read this except for educational purposes.


The trick is to use include! to directly import source code.

Filesystem

do-not-do-this
├── Cargo.toml
├── src
│   ├── dog-head.rs
│   ├── dog-tail.rs
│   ├── dog.rs
│   └── main.rs

src/main.rs

mod dog;

fn main() {
    dog::bark();
    dog::wag();
}

src/dog.rs

include!("dog-head.rs");
include!("dog-tail.rs");

src/dog-head.rs

pub fn bark() {
    eprintln!("Woof");
}

src/dog-tail.rs

pub fn wag() {
    eprintln!("Swish");
}

Tags:

Module

Rust