213 lines
5.8 KiB
Swift
213 lines
5.8 KiB
Swift
//
|
|
// 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
|
|
}
|
|
}
|