Extensions.swift 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import Foundation
  2. @testable import Trio
  3. extension [ComputedPumpHistoryEvent] {
  4. func netInsulin() -> Decimal { compactMap(\.insulin).reduce(0, +) }
  5. }
  6. extension Decimal {
  7. func isWithin(_ error: Decimal, of value: Decimal) -> Bool {
  8. (self - value).magnitude <= error
  9. }
  10. }
  11. extension Encodable {
  12. var prettyPrintedJSON: String? {
  13. let encoder = JSONCoding.encoder
  14. encoder.outputFormatting = [.prettyPrinted, .withoutEscapingSlashes, .sortedKeys]
  15. do {
  16. let data = try encoder.encode(self)
  17. return String(data: data, encoding: .utf8)
  18. } catch {
  19. return nil
  20. }
  21. }
  22. }
  23. extension IobResult {
  24. func approximatelyEquals(_ rhs: IobResult) -> Bool {
  25. // Compare all properties
  26. guard iob.isWithin(0.001, of: rhs.iob),
  27. activity.isWithin(0.0001, of: rhs.activity),
  28. basaliob.isWithin(0.001, of: rhs.basaliob),
  29. bolusiob.isWithin(0.001, of: rhs.bolusiob),
  30. netbasalinsulin.isWithin(0.05, of: rhs.netbasalinsulin),
  31. bolusinsulin.isWithin(0.001, of: rhs.bolusinsulin),
  32. time == rhs.time,
  33. lastBolusTime == rhs.lastBolusTime
  34. else {
  35. return false
  36. }
  37. // Compare nested IobWithZeroTemp
  38. guard iobWithZeroTemp.iob.isWithin(0.001, of: rhs.iobWithZeroTemp.iob),
  39. iobWithZeroTemp.activity.isWithin(0.0001, of: rhs.iobWithZeroTemp.activity),
  40. iobWithZeroTemp.basaliob.isWithin(0.001, of: rhs.iobWithZeroTemp.basaliob),
  41. iobWithZeroTemp.bolusiob.isWithin(0.001, of: rhs.iobWithZeroTemp.bolusiob),
  42. iobWithZeroTemp.netbasalinsulin.isWithin(0.05, of: rhs.iobWithZeroTemp.netbasalinsulin),
  43. iobWithZeroTemp.bolusinsulin.isWithin(0.001, of: rhs.iobWithZeroTemp.bolusinsulin),
  44. iobWithZeroTemp.time == rhs.iobWithZeroTemp.time
  45. else {
  46. return false
  47. }
  48. // Compare optional LastTemp
  49. if let selfTemp = lastTemp, let rhsTemp = rhs.lastTemp {
  50. guard let selfDuration = selfTemp.duration, let rhsDuration = rhsTemp.duration, selfDuration.isWithin(
  51. 0.01,
  52. of: rhsDuration
  53. ) else {
  54. return false
  55. }
  56. // Both are non-nil, compare their properties
  57. return selfTemp.rate == rhsTemp.rate &&
  58. selfTemp.timestamp == rhsTemp.timestamp &&
  59. selfTemp.started_at == rhsTemp.started_at &&
  60. selfTemp.date == rhsTemp.date
  61. } else {
  62. // Both should be nil for equality
  63. return lastTemp == nil && rhs.lastTemp == nil
  64. }
  65. }
  66. }