How to move a struct's implementation into a separate file without putting it in a submodule?

Viewed 303

I have this main function:

mod tools;

fn main() {
    let mut factory = tools::TerminalFactory::new();
    let trm: tools::Terminal;

    trm = factory.create("TTY1".to_string());
    println!("{}", trm);

    std::process::exit(0);
}

This is tools/mod.rs:

pub struct Terminal {
    id: u32,
    pub name: String
}

impl Terminal {
    pub fn get_id(self: &Self) -> u32 {
        self.id
    }
}

impl std::fmt::Display for Terminal {
    fn fmt(self: &Self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "TERMINAL#{} ({})", self.id, self.name)
    }
}

pub struct TerminalFactory {
    next_id: u32
}

impl TerminalFactory {
    pub fn new() -> TerminalFactory {
        TerminalFactory {
            next_id: 0
        }
    }

    pub fn create(self: &mut Self, name: String) -> Terminal {
        self.next_id += 1;

        Terminal {
            id: self.next_id,
            name: name
        }
    }
}

As you can see I have two structs in tools: tools::TerminalFactory and tools::Terminal. What I want to do is have those two structs implemented in two separate files, because the tools module will be pretty crowded and I don't want to clutter it with thousands of lines of code.

I can't come up with a way to move this code to separate files and keep it in tools. What I get when I move it to other files is that in tools/mod.rs I have to define the mod:

mod terminal;
mod terminal_factory;

But this moves the structs to tools::terminal_factory::TerminalFactory and tools::terminal::Terminal, which is not what I want.

How is this done in a rustical way without a *.toml and without cargo?

I will certainly use cargo, but I want to understand beforehand how to do this without it.

1 Answers

You usually reexport deeper types when you don't want to expose this modular structure.

Here, your tools/mod.rs file would be

mod terminal;
mod terminal_factory;

pub use {
    self::terminal::Terminal,
    self::terminal_factory::TerminalFactory,
};

The pub use enables external code to use the TerminalFactory type as if it was declared in the upper module.

Related