[Rust Guide] 7.3. Path Pt. 2 - Accessing Parent Modules and Pub on Structs and Enums

rust dev.to

If you find this helpful, please like, bookmark, and follow. To keep learning along, follow this series.

7.3.1 super

We can access items in a parent module’s path by using super at the start of a path, just like using .. syntax to start a file-system path. For example:

fn deliver_order() {}

mod back_of_house {
    fn fix_incorrect_order() {
        cook_order();
        super::deliver_order();
    }

    fn cook_order() {}
}
Enter fullscreen mode Exit fullscreen mode

Of course, you can use an absolute path to achieve the same result:

fn deliver_order() {}

mod back_of_house {
    fn fix_incorrect_order() {
        cook_order();
        crate::deliver_order();
    }

    fn cook_order() {}
}
Enter fullscreen mode Exit fullscreen mode

7.3.2 pub struct

If you put the pub keyword before struct, the struct becomes public, as shown below:

mod back_of_house {
    pub struct Breakfast {
        toast: String,
        seasonal_fruit: String,
    }
}
Enter fullscreen mode Exit fullscreen mode

Note that although this struct is public, the fields inside a struct are private by default, unless you add the pub keyword.

In Rust, in most cases if something does not have pub, then it is private. (Special cases will be discussed later.)

Making a field public is also simple. Here is the code after changing toast in Breakfast to public:

mod back_of_house {
    pub struct Breakfast {
        pub toast: String,
        seasonal_fruit: String,
    }
}
Enter fullscreen mode Exit fullscreen mode

Let’s look at a more complex example:

mod back_of_house {
    pub struct Breakfast {
        pub toast: String,
        seasonal_fruit: String,
    }

    impl Breakfast {
        pub fn summer(toast: &str) -> Breakfast {
            Breakfast {
                toast: String::from(toast),
                seasonal_fruit: String::from("peaches"),
            }
        }
    }
}

pub fn eat_at_restaurant(){
    let mut meal = back_of_house::Breakfast::summer("Rye");
    meal.toast = String::from("Wheat");
}
Enter fullscreen mode Exit fullscreen mode
  • On top of the struct, we define an associated function summer, whose parameter is the string slice toast and whose return value is Breakfast. The value of Breakfast.toast will be the value of that argument, and the value of Breakfast.seasonal_fruit will be set to peaches. In essence, summer is a constructor that creates an instance of Breakfast.
  • In the eat_at_restaurant function, we first use a relative path to call summer and construct an instance, then assign it to the mutable variable meal. The toast field in meal is set to Rye, and seasonal_fruit is peaches as written in the constructor. On the next line, because the Breakfast struct is public, meal.toast can be modified directly, and here it is changed to Wheat.

Would writing meal.seasonal_fruit = String::from("buleberries"); inside the eat_at_restaurant function cause an error? The answer is yes, because fields inside a struct are private by default. seasonal_fruit was not declared public, so external code cannot modify it, and this line attempts to modify it, which causes an error.

7.3.3 pub enum

Just like struct, an enum also becomes public if you add the pub keyword. For example:

mod back_of_house {
    pub enum Appetizer {
        Soup,
        Salad,
    }
}

pub fn eat_at_restaurant() {
    let order1 = back_of_house::Appetizer::Soup;
    let order2 = back_of_house::Appetizer::Salad;
}
Enter fullscreen mode Exit fullscreen mode

But unlike struct, where the fields are private by default, the variants of a public enum are public by default, so you do not need to put pub before each variant. This differs from Rust’s default-private rule because only public variants on a public enum are useful, while having some private fields in a struct does not affect its use.

But note that the prerequisite for variants of an enum to be public is that the enum itself is declared public.

Source: dev.to

arrow_back Back to Tutorials