What most beginners (aka me perpetually) want to do is move some functions from one file like lib.rs
into a file named submod.rs
and access the functions in it as submod::myfunc
. The answer that inspired me to write this suggests lexer::lexer::lex_stuff()
which is slightly infuriating. We should never see a name twice for no serious reason. And adding another name, as the book does with hosting
isn't helpful since naming is a hard problem in CS.
So hence, here's how to make a crepe instead of a stack of crepes (using the example from the book):
lib.rs
mod front_of_house;
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
front_of_house::seating_capacity();
hosting::add_to_waitlist();
}
front_of_house.rs (or optionally front_of_house/mod.rs)
pub fn seating_capacity() {}
pub mod hosting {
pub fn add_to_waitlist() {}
}
Now if you add a pub fn put_up_chairs() {}
to lib.rs
and decide, wait a minute, that belongs in front_of_house
(but not hosting
), you can simply move the function over to front_of_house.rs
and refer to it in lib.rs
as front_of_house::put_up_chairs()
. Simple..? I hope? I'm writing to myself in the future when I forget this and find this answer again, not you gentle reader.
Note everything gets more exciting when the pub
keyword is gone or altered, at which point maybe you should reread the book. ;)
Also one more thing, adding pub use front_of_house;
after the mod front_of_house
is an error, because you already have declared the module. If you do cargo gives a loud answer (because it assumes you know what you're doing, if you're like me and program computers by bashing rocks together, you don't)
error[E0255]: the name `front_of_house` is defined multiple times
--> src/lib.rs:2:9
|
1 | mod front_of_house;
| ------------------- previous definition of the module `front_of_house` here
2 | pub use crate::front_of_house;
| ^^^^^^^^^^^^^^^^^^^^^ `front_of_house` reimported here
|
= note: `front_of_house` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
|
2 | pub use crate::front_of_house as other_front_of_house;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0365]: `front_of_house` is only public within the crate, and cannot be re-exported outside
--> src/lib.rs:2:9
|
2 | pub use crate::front_of_house;
| ^^^^^^^^^^^^^^^^^^^^^ re-export of crate public `front_of_house`
|
= note: consider declaring type or module `front_of_house` with `pub`
If you made the above mistake of 'double using' it's ok, it's a little odd that the mod
keyword also gives you a use
for free. But it does and we should be thankful for it. :)
Motivation
In over a decade I've never written an answer on SO. But I've hit this question so many times and been so absolutely twisted in knots by the "Please take the time to re-read" answer by beloved rust wiz @Shepmaster that I'm writing an answer. The Rust Book example is like a recipe for baking a crepe cake before showing you how to make a single crepe, at least as of the 2nd edition.