Last active
February 19, 2023 06:17
-
-
Save mxgrey/992a48150bba909cf86d0e196589b2f0 to your computer and use it in GitHub Desktop.
Sketch of optional trait bounds idea for Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| fn serve_customer<C>(mut customer: &C) -> u32 | |
| where | |
| // When a trait bound is wrapped in [], that means it's optional | |
| C: Noisy + [Hungry] + [Thirsty] | |
| { | |
| // Mandatory trait bounds can always be called | |
| let order = customer.talk(); | |
| let food_price: u32 = with C as Hungry { | |
| // This block only gets compiled if C implements Hungry. | |
| // Otherwise, only the else block will be compiled. | |
| let food_order: C::Food = order.into(); | |
| let food_price = food_order.price(); | |
| customer.eat(food_order); | |
| food_price | |
| } else { | |
| 0 | |
| }; | |
| let drink_price: u32 = with C as Thirsty { | |
| // This block only gets compiled if C implements Thirsty. | |
| let drink_order: C::Drink = order.into(); | |
| let drink_price = drink_order.price(); | |
| customer.drink(drink_order); | |
| drink_price | |
| } else { | |
| 0 | |
| }; | |
| let price = with C as Hungry + Thirsty { | |
| // This block only gets compiled if C implements both Hungry and Thirsty. | |
| // Apply a set meal discount | |
| let sum = food_price + drink_price; | |
| sum - sum/10 | |
| } else { | |
| food_price + drink_price | |
| }; | |
| price | |
| } | |
| trait Noisy { | |
| fn talk(&self) -> Order; | |
| } | |
| trait Costly { | |
| fn price(&self) -> u32; | |
| } | |
| trait Hungry { | |
| type Food: From<Order> + Costly; | |
| fn eat(&mut self, food: Self::Food); | |
| } | |
| trait Thirsty { | |
| type Drink: From<Order> + Costly; | |
| fn drink(&mut self, drink: Self::Drink); | |
| } | |
| #[derive(Clone, Copy)] | |
| struct Order { /* ignore details */ } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment