Visibility and Privacy
In this chapter, we'll explore control access to code with pub and private visibility.
Visibility and Privacy
By default, items in Mana are private—they can only be accessed within the same module. Use pub to make items accessible from other modules.
Private by Default
module math
// Private - only accessible within this module
fn helper_function() -> int {
return 42
}
// Public - accessible from other modules
pub fn add(a: int, b: int) -> int {
return a + b + helper_function() // Can use private helper
}Making Items Public
Use pub before any declaration:
module shapes
// Public struct
pub struct Circle {
pub radius: f32, // Public field
center_x: f32, // Private field
center_y: f32, // Private field
}
// Public function
pub fn area(c: Circle) -> f32 {
return 3.14159 * c.radius * c.radius
}
// Public constant
pub const PI: f64 = 3.14159265358979Struct Field Visibility
Struct fields have their own visibility:
module user
pub struct User {
pub name: string, // Public - anyone can read
pub email: string, // Public
password_hash: string, // Private - only this module
internal_id: int, // Private
}
impl User {
// Public constructor - the only way to create a User
pub fn new(name: string, email: string, password: string) -> User {
return User {
name: name,
email: email,
password_hash: hash(password),
internal_id: generate_id(),
}
}
// Public method
pub fn display_name(self) -> string {
return self.name
}
// Private helper
fn hash(password: string) -> string {
// Internal hashing logic
}
}Enum Visibility
When an enum is public, all its variants are public:
module status
pub enum Status {
Active,
Inactive,
Pending,
}
// All variants (Active, Inactive, Pending) are accessibleTrait Visibility
module traits
pub trait Drawable {
fn draw(self) -> void
fn bounds(self) -> Rectangle
}
// Implementations inherit visibility from the trait
pub impl Drawable for Circle {
fn draw(self) -> void {
// ...
}
fn bounds(self) -> Rectangle {
// ...
}
}Why Privacy Matters
Privacy helps you:
- Hide implementation details — Change internals without breaking users
- Enforce invariants — Control how data is modified
- Create clean APIs — Expose only what's necessary
module counter
pub struct Counter {
value: int, // Private - can't be modified directly
}
impl Counter {
pub fn new() -> Counter {
return Counter { value: 0 }
}
pub fn increment(mut self) -> void {
self.value = self.value + 1 // Controlled modification
}
pub fn get(self) -> int {
return self.value // Read-only access
}
}Continue to Imports and Paths.