Here I have a PizzaFactory
which lets you add either Veggie
or a Meat
topping(s). I will need to preserve what kind of Veggie
or Meat
is added.
I discovered that you cannot nest enums so I went with the code below:
/**
Create a program that solves the following requirements:
>lets use create a pizza
>pizza can either be "Personal" or "Family" size with a price of $9 and $18 respectively
>ability to add veggie or meat toppings: veggie toppings at 5% to the base price while meat toppings as 10% to the base price
>veggie toppings are Mushrooms, Green Peppers, Onions, Tomatoes, and Pineapple
>meat toppings are Sausage, Chicken, Pepperoni, and Bacon
>you should be able to get the price of a pizza. e.g. a personal pizza with mushroom and sausage is $9 * (1 + (.05 + .10)) or $10.35
>you should be able to get the description of the pizza at any time. e.g. "A Personal Pizza with Mushrooms and Sausage"
*/
enum PizzaSize {
Personal,
Family,
}
enum Veggies {
Mushrooms,
GreenPeppers,
Onions,
Tomatoes,
Pineapples,
}
enum Meats {
Sausage,
Chicken,
Pepperoni,
Bacon,
}
enum PizzaToppings {
Veggies,
Meats,
}
struct Pizza {
size: PizzaSize,
topping: Vec<PizzaToppings>,
}
impl Pizza {
pub fn price(&self) -> f32 {
self.topping.iter().fold(
match self.size {
PizzaSize::Personal => 9.,
PizzaSize::Family => 18.,
},
|total, topping| match topping {
PizzaToppings::Veggies => total * 1.05,
PizzaToppings::Meats => total * 1.1,
},
)
}
}
struct PizzaFactory {
pizza: Pizza,
}
impl PizzaFactory {
pub fn new(size: PizzaSize) -> Self {
Self {
pizza: Pizza {
size: size,
topping: vec![],
},
}
}
pub fn with(mut self, topping: PizzaToppings) -> Self {
self.pizza.topping.push(topping);
Self { pizza: self.pizza }
}
pub fn bake(&self) -> Pizza {
self.pizza
}
}
fn main() {
let pizza = PizzaFactory::new(PizzaSize::Personal).with(PizzaToppings::Meats::Chicken).with(Veggies::GreenPeppers).bake();
}
Playground link: Rust Playground
Note that the with
method in the PizzaFactory
can either take a Veggie
or a Meat
topping. Now the compiler complains that the method requires a PizzaTopping
type but it fails to understand that it composes the Veggies
and the Meats
enums described above it.
How can I inherit or compose other enums?
I can, obviously use traits but that'd mean a lot of boilerplate code and enums/variants make more sense here imo.
Perhaps the with
method should accept a typeclass that is satisfied by both Veggie
and the Meat
enum. I don't know how to express that in Rust.