Context:
I am writing an app where I want to display the nutritional facts of each menu item. I wanted to have the flexibility of converting using the Measurement class.
Problem:
The problem is that calories is measured in Measurement < UnitEnergy > , while other properties like proteins are measured in Measurement < UnitMass > . I decided to make the variable of type Measurement < Unit > so it could handle both types. But then I loose all possibility to do conversions or operations with the variable.
This function would give me Error (which makes sense, I just don't know what would be the best way to approach this)
Binary operator '/' cannot be applied to two 'Measurement < Unit > ' operands
func getPercentage() -> Double {
return value / property.referenceIntake
}
If I try to cast it I get this error
Cast from 'Measurement < Unit > ' to unrelated type 'Measurement < UnitMass > ' always fails
if let massUnitMeasurement = value as? Measurement<UnitMass>, let referenceMeasurement = property.referenceIntake as? {
....
}
What I have so far:
struct NutritionInformation {
let property: NutritionProperties
let value: Measurement<Unit>
var formattedValue: String {
let formatter = MeasurementFormatter()
formatter.unitStyle = .medium
formatter.unitOptions = .providedUnit
return formatter.string(from: value)
}
}
enum NutritionProperties {
case calories
case carbohydrate
case cholesterol
case fat
case saturatedFat
case fibre
case protein
case sodium
case sugar
var unit: Unit {
switch self {
case .calories: return UnitEnergy.kilocalories
case .cholesterol, .sodium: return UnitMass.milligrams
default: return UnitMass.grams
}
}
var referenceIntake: Measurement<Unit> {
switch self {
case .calories: return Measurement(value: 2000, unit: unit)
case .fat: return Measurement(value: 70, unit: unit)
case .saturatedFat: return Measurement(value: 20, unit: unit)
case .carbohydrate: return Measurement(value: 260, unit: unit)
case .fibre: return Measurement(value: 30, unit: unit)
case .sugar: return Measurement(value: 90, unit: unit)
case .protein: return Measurement(value: 50, unit: unit)
case .sodium: return Measurement(value: 2300, unit: unit)
case .cholesterol: return Measurement(value: 300, unit: unit)
}
}
}