// ./src/error/option_unwrap/map.md #![allow(dead_code)] #[derive(Debug)] enum Food { Apple, Carrot, Potato } #[derive(Debug)] struct Peeled(Food); #[derive(Debug)] struct Chopped(Food); #[derive(Debug)] struct Cooked(Food); // Peeling food. If there isn't any, then return `None`. // Otherwise, return the peeled food. fn peel(food: Option) -> Option { match food { Some(food) => Some(Peeled(food)), None => None, } } // Chopping food. If there isn't any, then return `None`. // Otherwise, return the chopped food. fn chop(peeled: Option) -> Option { match peeled { Some(Peeled(food)) => Some(Chopped(food)), None => None, } } // Cooking food. Here, we showcase `map()` instead of `match` for case handling. fn cook(chopped: Option) -> Option { chopped.map(|Chopped(food)| Cooked(food)) } // A function to peel, chop, and cook food all in sequence. // We chain multiple uses of `map()` to simplify the code. fn process(food: Option) -> Option { food.map(|f| Peeled(f)) .map(|Peeled(f)| Chopped(f)) .map(|Chopped(f)| Cooked(f)) } // Check whether there's food or not before trying to eat it! fn eat(food: Option) { match food { Some(food) => println!("Mmm. I love {:?}", food), None => println!("Oh no! It wasn't edible."), } } fn part0() { let apple = Some(Food::Apple); let carrot = Some(Food::Carrot); let potato = None; let cooked_apple = cook(chop(peel(apple))); let cooked_carrot = cook(chop(peel(carrot))); // Let's try the simpler looking `process()` now. let cooked_potato = process(potato); eat(cooked_apple); eat(cooked_carrot); eat(cooked_potato); } pub fn main() { part0(); }