Basic ingredient amount adjustment

This commit is contained in:
VincentMeilinger
2024-03-11 20:07:50 +01:00
parent 1c0c10957c
commit eae72eb0ce
6 changed files with 512 additions and 14 deletions

View File

@@ -0,0 +1,212 @@
//
// Units.swift
// Nextcloud Cookbook iOS Client
//
// Created by Vincent Meilinger on 11.03.24.
//
import Foundation
import SwiftUI
// MARK: - Ingredient Units
enum MeasurementUnit {
// Volume Metric
case milliLiter, centiLiter, deciLiter, liter
// Volume Imperial
case teaspoon, tablespoon, cup, pint, quart, gallon, gill, fluidOunce // Please just use metric
// Weight Metric
case milliGram, gram, kilogram
// Weight Imperial
case ounce, pound
// Other
case pinch, dash, smidgen
var localizedDescription: [LocalizedStringKey] {
switch self {
case .milliLiter:
return ["milliliter", "millilitre", "ml", "cc"]
case .centiLiter:
return ["centiliter", "centilitre", "cl"]
case .deciLiter:
return ["deciliter", "decilitre", "dl"]
case .liter:
return ["liter", "litre", "l"]
case .teaspoon:
return ["teaspoon", "tsp"]
case .tablespoon:
return ["tablespoon", "tbsp"]
case .cup:
return ["cup", "c"]
case .pint:
return ["pint", "pt"]
case .quart:
return ["quart", "qt"]
case .gallon:
return ["gallon", "gal"]
case .gill:
return ["gill", "gi"]
case .fluidOunce:
return ["fluid ounce", "fl oz"]
case .milliGram:
return ["milligram", "mg"]
case .gram:
return ["gram", "g"]
case .kilogram:
return ["kilogram", "kg"]
case .ounce:
return ["ounce", "oz"]
case .pound:
return ["pound", "lb"]
case .pinch:
return ["pinch"]
case .dash:
return ["dash"]
case .smidgen:
return ["smidgen"]
}
}
static func convert(value: Double, from fromUnit: MeasurementUnit, to toUnit: MeasurementUnit) -> Double? {
let (baseValue, _) = MeasurementUnit.toBaseUnit(value: value, unit: fromUnit)
return MeasurementUnit.fromBaseUnit(value: baseValue, targetUnit: toUnit)
}
private static func baseUnit(of unit: MeasurementUnit) -> MeasurementUnit {
switch unit {
// Volume Metric (all converted to liters)
case .milliLiter, .centiLiter, .deciLiter, .liter, .teaspoon, .tablespoon, .cup, .pint, .quart, .gallon, .gill, .fluidOunce, .dash:
return .liter
// Weight (all converted to grams)
case .milliGram, .gram, .kilogram, .ounce, .pound, .pinch, .smidgen:
return .gram
}
}
private static func toBaseUnit(value: Double, unit: MeasurementUnit) -> (Double, MeasurementUnit) {
guard abs(value) >= Double(1e-10) else {
return (0, unit)
}
switch unit {
case .milliLiter:
return (value/1000, .liter)
case .centiLiter:
return (value/100, .liter)
case .deciLiter:
return (value/10, .liter)
case .liter:
return (value, .liter)
case .teaspoon:
return (value * 0.005, .liter)
case .tablespoon:
return (value * 0.015, .liter)
case .cup:
return (value * 0.25, .liter)
case .pint:
return (value * 0.5, .liter)
case .quart:
return (value * 0.946, .liter)
case .gallon:
return (value * 3.8, .liter)
case .gill:
return (value * 0.17, .liter)
case .fluidOunce:
return (value * 0.03, .liter)
case .milliGram:
return (value * 0.001, .gram)
case .gram:
return (value, .gram)
case .kilogram:
return (value * 1000, .gram)
case .ounce:
return (value * 30, .gram)
case .pound:
return (value * 450, .gram)
case .pinch:
return (value * 0.3, .gram)
case .dash:
return (value * 0.000625, .liter)
case .smidgen:
return (value * 0.15, .gram)
}
}
static private func fromBaseUnit(value: Double, targetUnit: MeasurementUnit) -> Double {
guard abs(value) >= Double(1e-10) else {
return 0
}
switch targetUnit {
case .milliLiter:
return value * 1000
case .centiLiter:
return value * 100
case .deciLiter:
return value * 10
case .liter:
return value
case .teaspoon:
return value / 0.005
case .tablespoon:
return value / 0.015
case .cup:
return value / 0.25
case .pint:
return value / 0.5
case .quart:
return value / 0.946
case .gallon:
return value / 3.8
case .gill:
return value / 0.17
case .fluidOunce:
return value / 0.03
case .milliGram:
return value * 1000
case .gram:
return value
case .kilogram:
return value / 1000
case .ounce:
return value / 30
case .pound:
return value / 450
case .pinch:
return value / 0.3
case .dash:
return value / 0.000625
case .smidgen:
return value / 0.15
}
}
}
enum TemperatureUnit {
case fahrenheit, celsius
var localizedDescription: [LocalizedStringKey] {
switch self {
case .fahrenheit:
["fahrenheit", "f"]
case .celsius:
["celsius", "c"]
}
}
static func celsiusToFahrenheit(_ celsius: Double) -> Double {
return celsius * 9.0 / 5.0 + 32.0
}
static func fahrenheitToCelsius(_ fahrenheit: Double) -> Double {
return (fahrenheit - 32.0) * 5.0 / 9.0
}
}