GlucoseRange.swift 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. //
  2. // GlucoseRange.swift
  3. // LoopKit
  4. //
  5. // Created by Nathaniel Hamming on 2021-03-16.
  6. // Copyright © 2021 LoopKit Authors. All rights reserved.
  7. //
  8. import Foundation
  9. import HealthKit
  10. public struct GlucoseRange {
  11. public let range: DoubleRange
  12. public let unit: HKUnit
  13. public init(minValue: Double, maxValue: Double, unit: HKUnit) {
  14. self.init(range: DoubleRange(minValue: minValue, maxValue: maxValue), unit: unit)
  15. }
  16. public init(range: DoubleRange, unit: HKUnit) {
  17. precondition(unit == .milligramsPerDeciliter || unit == .millimolesPerLiter)
  18. self.range = range
  19. self.unit = unit
  20. }
  21. public var isZero: Bool {
  22. return abs(range.minValue) < .ulpOfOne && abs(range.maxValue) < .ulpOfOne
  23. }
  24. public var quantityRange: ClosedRange<HKQuantity> {
  25. range.quantityRange(for: unit)
  26. }
  27. }
  28. extension GlucoseRange: Hashable {}
  29. extension GlucoseRange: Equatable {}
  30. extension GlucoseRange: RawRepresentable {
  31. public typealias RawValue = [String:Any]
  32. public init?(rawValue: RawValue) {
  33. guard let rawRange = rawValue["range"] as? DoubleRange.RawValue,
  34. let range = DoubleRange(rawValue: rawRange),
  35. let bloodGlucoseUnit = rawValue["bloodGlucoseUnit"] as? String else
  36. {
  37. return nil
  38. }
  39. self.range = range
  40. self.unit = HKUnit(from: bloodGlucoseUnit)
  41. }
  42. public var rawValue: RawValue {
  43. return [
  44. "range": range.rawValue,
  45. "bloodGlucoseUnit": unit.unitString
  46. ]
  47. }
  48. }
  49. extension GlucoseRange: Codable {
  50. public init(from decoder: Decoder) throws {
  51. let container = try decoder.container(keyedBy: CodingKeys.self)
  52. unit = HKUnit(from: try container.decode(String.self, forKey: .bloodGlucoseUnit))
  53. range = try container.decode(DoubleRange.self, forKey: .range)
  54. }
  55. public func encode(to encoder: Encoder) throws {
  56. var container = encoder.container(keyedBy: CodingKeys.self)
  57. try container.encode(range, forKey: .range)
  58. try container.encode(unit.unitString, forKey: .bloodGlucoseUnit)
  59. }
  60. private enum CodingKeys: String, CodingKey {
  61. case bloodGlucoseUnit
  62. case range
  63. }
  64. }