Say I have a bakery and an inventory of ingredients:
enum Ingredient { case flower = 1 case sugar = 2 case yeast = 3 case eggs = 4 case milk = 5 case almonds = 6 case chocolate = 7 case salt = 8 }
The rawValue case represents the inventory number.
Then I have two recipes:
Chocolate cake:
- 500 g of flower
- 300 g sugar
- 3 eggs
- 200 ml of milk
- 200 g chocolate
Almond cake:
- 300 g of flower
- 200 g sugar
- 20 g yeast
- 200 g almonds
- 5 eggs
- 2g salt
Now I define a function
func bake(with ingredients: [Ingredient]) -> Cake
Of course, I trust my employees, but I still want to make sure that they use only the right ingredients to bake the cake. 😉
I could do this by specifying two separate enumerations, for example:
enum ChocolateCakeIngredient { case flower case sugar case eggs case milk case chocolate } enum AlmondCakeIngredient { case flower case sugar case yeast case eggs case almonds case salt }
and bake the cake as follows:
// in chocolate cake class / struct: func bake(with ingredients: [ChocolateCakeIngredient]) -> ChocolateCake // in almond cake class / struct: func bake(with ingredients: [AlmondCakeIngredient]) -> AlmondCake
But then I will have to redefine the same ingredients over and over again, as many ingredients are used for both cakes. I really don't want to do this - especially since the enumerations include inventory numbers such as rawValue s.
This leads me to the question of is there a way in Swift to restrict an enumeration to some cases of another enumeration ? Something like (pseudo-code):
enum ChocolateCakeIngredient: Ingredient { allowedCases: case flower case sugar case eggs case milk case chocolate } enum AlmondCakeIngredient: Ingredient { allowedCases: case flower case sugar case yeast case eggs case almonds case salt }
Is such an essay possible? How can i do this?
Or maybe there is another template that I can use for this scenario?
Update
Of all the comments and answers to this question, I thought that the example that I chose for this question was a little inappropriate, because it did not reduce the essence of the problem and left a loophole regarding type safety.
Since all of the posts on this page relate to this particular example, I created a new question in Stackoverflow with an example that is easier to understand and hit a nail on my head:
➡️ Same question with a more specific example