Created
April 10, 2020 22:15
-
-
Save thexande/33a91ee42dc2e07ed5ada6001fabc7ba to your computer and use it in GitHub Desktop.
A coffee machine implementation using swift.
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
protocol ResourcesContaining { | |
var beans: Double { get set } | |
var milk: Double { get set } | |
var water: Double { get set } | |
func hasRequiredResources(for resourceSet: [Resource]) -> Bool | |
} | |
extension ResourcesContaining { | |
func hasRequiredResources(for resourceSet: [Resource]) -> Bool { | |
var currentBeans = self.beans | |
var currentMilk = self.milk | |
var currentWater = self.milk | |
resourceSet.forEach { | |
switch $0 { | |
case .beans(let ounces): | |
currentBeans -= ounces | |
case .milk(let ounces): | |
currentMilk -= ounces | |
case .water(let ounces): | |
currentWater -= ounces | |
} | |
} | |
return currentBeans > 0 && currentMilk > 0 && currentWater > 0 | |
} | |
} | |
enum MachineState { | |
case ready | |
case vending | |
case requiresResources | |
} | |
protocol MachineStateProviding { | |
var resourceStore: ResourcesContaining { get set } | |
var state: MachineState { get set } | |
} | |
final class ResourceStore: ResourcesContaining { | |
var beans: Double = 0 | |
var milk: Double = 0 | |
var water: Double = 0 | |
} | |
enum Size: Double { | |
case small = 8 | |
case medium = 12 | |
case large = 16 | |
} | |
enum Style { | |
case espresso | |
case coffee | |
case late | |
} | |
struct Recipie { | |
let resources: [Resource] | |
let style: Style | |
let size: Size | |
} | |
struct Drink { | |
let ounces: Double | |
let style: Style | |
let size: Size | |
} | |
enum Resource { | |
case milk(ounces: Double) | |
case beans(ounces: Double) | |
case water(ounces: Double) | |
} | |
final class Machine: MachineStateProviding { | |
var resourceStore: ResourcesContaining = ResourceStore() | |
var state: MachineState = .ready | |
} | |
protocol DrinkProducing { | |
func make(recipie: Recipie) -> Drink | |
} | |
enum DrinkError: Error { | |
case notEnoughResources | |
} | |
extension DrinkProducing where Self: MachineStateProviding { | |
mutating func make(recipie: Recipie) -> Result<Drink, DrinkError> { | |
state = .vending | |
guard resourceStore.hasRequiredResources(for: recipie.resources) else { | |
return .failure(.notEnoughResources) | |
} | |
var totalOunces: Double = 0 | |
for resource in recipie.resources { | |
switch resource { | |
case .milk(let ounces): | |
resourceStore.milk -= ounces | |
totalOunces += ounces | |
case .beans(let ounces): | |
resourceStore.beans -= ounces | |
totalOunces += ounces | |
case .water(let ounces): | |
resourceStore.water -= ounces | |
totalOunces += ounces | |
} | |
} | |
return .success(.init(ounces: totalOunces, | |
style: recipie.style, | |
size: recipie.size)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment