In Rust, the `pub` keyword is used to make modules, functions, structs, enums, and constants public. By default, all these items are private to their parent modules. Let's understand this with an example.
Consider the following code:
Rust
mod front_of_house {
pub mod hosting {
fn add_to_waitlist() {}
}
}
pub fn eat_at_restaurant() {
// Absolute path
crate::front_of_house::hosting::add_to_waitlist();
// Relative path
front_of_house::hosting::add_to_waitlist();
}
Here, we have made the `hosting` module public using the `pub` keyword. However, the `add_to_waitlist` function inside the `hosting` module is still private. This is why the code will not compile and will throw an error.
The `pub` keyword on a module only lets code in its ancestor modules refer to it, not access its inner code. To make the `add_to_waitlist` function accessible, we need to make it public as well:
Rust
mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub fn eat_at_restaurant() {
// Absolute path
crate::front_of_house::hosting::add_to_waitlist();
// Relative path
front_of_house::hosting::add_to_waitlist();
}
Now, the code will compile successfully. The `pub` keyword allows us to use these paths in `add_to_waitlist` with respect to the privacy rules.
In the absolute path, we start with `crate`, the root of our crate’s module tree. The `front_of_house` module is defined in the crate root. While `front_of_house` isn’t public, because the `eat_at_restaurant` function is defined in the same module as `front_of_house`, we can refer to `front_of_house` from `eat_at_restaurant`.
In the relative path, the logic is the same as the absolute path except for the first step: rather than starting from the crate root, the path starts from `front_of_house`. The `front_of_house` module is defined within the same module as `eat_at_restaurant`, so the relative path starting from the module in which `eat_at_restaurant` is defined works.
If you plan on sharing your library crate so other projects can use your code, your public API is your contract with users of your crate that determines how they can interact with your code. There are many considerations around managing changes to your public API to make it easier for people to depend on your crate.