Rust Visibility Levels: A Guide to Access Control

Drashti Shah
2 min readApr 9, 2023

In Rust, visibility levels determine the accessibility of items (functions, structs, enums, etc.) across different modules and crates. By default, items have private visibility, meaning they can only be accessed within the current module. You can use visibility modifiers to change the visibility of an item.

Understanding Rust’s Visibility Levels

Here’s a more detailed explanation of Rust’s visibility levels.

1. Private (no visibility modifier)

Items without a visibility modifier are private by default. They can only be accessed within the current module, and not from other modules or crates. This is the most restrictive level of visibility.

fn private_function() {
// This function is only accessible within its module
}

2. Public (pub)

When an item is marked pub, it becomes publicly accessible from any module, including external crates that depend on the current crate. This is the most permissive level of visibility.

pub fn public_function() {
// This function is accessible from any module and external crates
}

3. Crate-level (pub(crate))

An item marked pub(crate) is public within the current crate, meaning it can be accessed from any module within the same crate. However, it is not accessible from other crates that depend on the current crate. This level of visibility is useful when you want to expose items internally while keeping them hidden from external users.

pub(crate) fn crate_level_function() {
// This function is accessible within the current crate only
}

4. Super-level (pub(super)):

The pub(super) visibility level makes an item public within the parent module (one level up) and its child modules. It is useful when you want to expose an item to the parent module but restrict access from unrelated modules.

pub(super) fn super_level_function() {
// This function is accessible in the parent module and its child modules
}

5. Path-based (pub(in path::to::module)):

With this visibility level, an item becomes public within the specified module path and its child modules. This allows for fine-grained control over the visibility of an item.

pub(in crate::path::to::module) fn path_based_function() {
// This function is accessible within the specified module and its child modules
}

The Importance of Visibility Levels

These visibility levels allow you to control the exposure of your code’s components, enabling encapsulation and modular design. Understanding and using them effectively helps maintain a clean and organized codebase. By carefully choosing the appropriate visibility level for each component, you can build a robust and maintainable Rust project.

--

--

Drashti Shah

ESG & climate data scientist by day. Aspiring computational biologist by night.