forked from LoopKit/LoopAlgorithm
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLoopQuantity.swift
More file actions
73 lines (60 loc) · 2.27 KB
/
Copy pathLoopQuantity.swift
File metadata and controls
73 lines (60 loc) · 2.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//
// LoopQuantity.swift
// LoopAlgorithm
//
// Created by Cameron Ingham on 11/8/24.
//
import Foundation
public struct LoopQuantity: Hashable, Equatable, Comparable, Sendable {
public let unit: LoopUnit
private let value: Double
public init(unit: LoopUnit, doubleValue value: Double) {
self.unit = unit
self.value = value
}
public func `is`(compatibleWith unit: LoopUnit) -> Bool {
self.unit.conversionFactor(toUnit: unit) != nil
}
/**
@method doubleValueForUnit:
@abstract Returns the quantity value converted to the given unit.
@discussion Throws an exception if the receiver's value cannot be converted to one of the requested unit.
*/
public func doubleValue(for unit: LoopUnit) -> Double {
guard let conversionFactor = self.unit.conversionFactor(toUnit: unit) else {
fatalError("Conversion Error: \(self.unit.unitString) is not compatible with \(unit.unitString).")
}
if self.unit == unit {
return value
} else {
return value * conversionFactor
}
}
/**
@method compare:
@abstract Returns an NSComparisonResult value that indicates whether the receiver is greater than, equal to, or
less than a given quantity.
@discussion Throws an exception if the unit of the given quantity is not compatible with the receiver's unit.
*/
public func compare(_ quantity: LoopQuantity) -> ComparisonResult {
if value == quantity.doubleValue(for: unit) {
return .orderedSame
} else if value > quantity.doubleValue(for: unit) {
return .orderedDescending
} else {
return .orderedAscending
}
}
public static func <(lhs: LoopQuantity, rhs: LoopQuantity) -> Bool {
return lhs.compare(rhs) == .orderedAscending
}
public static func == (lhs: LoopQuantity, rhs: LoopQuantity) -> Bool {
guard lhs.unit != rhs.unit else {
return lhs.value == rhs.value
}
guard rhs.is(compatibleWith: lhs.unit) else {
return false
}
return lhs.doubleValue(for: lhs.unit) == rhs.doubleValue(for: lhs.unit)
}
}