FileStorage.swift 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import Combine
  2. import Disk
  3. import Foundation
  4. protocol FileStorage {
  5. func save<Value: JSON>(_ value: Value, as name: String) throws
  6. func savePublisher<Value: JSON>(_: Value, as name: String) -> AnyPublisher<Void, Error>
  7. func retrieve<Value: JSON>(_ name: String, as type: Value.Type) throws -> Value
  8. func retrievePublisher<Value: JSON>(_: String, as type: Value.Type) -> AnyPublisher<Value, Error>
  9. func append<Value: JSON>(_ newValue: Value, to name: String) throws
  10. func append<Value: JSON>(_ newValue: [Value], to name: String) throws
  11. func appendPublisher<Value: JSON>(_: Value, to name: String) -> AnyPublisher<Void, Error>
  12. func appendPublisher<Value: JSON>(_ newValue: [Value], to name: String) -> AnyPublisher<Void, Error>
  13. }
  14. final class BaseFileStorage: FileStorage {
  15. private let processQueue = DispatchQueue(label: "BaseFileStorage.processQueue")
  16. private var encoder: JSONEncoder {
  17. let encoder = JSONEncoder()
  18. encoder.outputFormatting = .prettyPrinted
  19. encoder.dateEncodingStrategy = .iso8601
  20. return encoder
  21. }
  22. private var decoder: JSONDecoder {
  23. let decoder = JSONDecoder()
  24. decoder.dateDecodingStrategy = .iso8601
  25. return decoder
  26. }
  27. func save<Value: JSON>(_ value: Value, as name: String) throws {
  28. try Disk.save(value, to: .documents, as: name, encoder: encoder)
  29. }
  30. func savePublisher<Value: JSON>(_ value: Value, as name: String) -> AnyPublisher<Void, Error> {
  31. Future { promise in
  32. self.processQueue.async {
  33. do {
  34. try self.save(value, as: name)
  35. promise(.success(()))
  36. } catch {
  37. promise(.failure(error))
  38. }
  39. }
  40. }
  41. .eraseToAnyPublisher()
  42. }
  43. func retrieve<Value: JSON>(_ name: String, as type: Value.Type) throws -> Value {
  44. try Disk.retrieve(name, from: .documents, as: type, decoder: decoder)
  45. }
  46. func retrievePublisher<Value: JSON>(_ name: String, as type: Value.Type) -> AnyPublisher<Value, Error> {
  47. Future { promise in
  48. self.processQueue.async {
  49. do {
  50. let value = try self.retrieve(name, as: type)
  51. promise(.success(value))
  52. } catch {
  53. promise(.failure(error))
  54. }
  55. }
  56. }
  57. .eraseToAnyPublisher()
  58. }
  59. func append<Value: JSON>(_ newValue: Value, to name: String) throws {
  60. try Disk.append(newValue, to: name, in: .documents, encoder: encoder)
  61. }
  62. func append<Value: JSON>(_ newValue: [Value], to name: String) throws {
  63. try Disk.append(newValue, to: name, in: .documents, encoder: encoder)
  64. }
  65. func appendPublisher<Value: JSON>(_ newValue: Value, to name: String) -> AnyPublisher<Void, Error> {
  66. Future { promise in
  67. self.processQueue.async {
  68. do {
  69. try self.append(newValue, to: name)
  70. promise(.success(()))
  71. } catch {
  72. promise(.failure(error))
  73. }
  74. }
  75. }
  76. .eraseToAnyPublisher()
  77. }
  78. func appendPublisher<Value: JSON>(_ newValue: [Value], to name: String) -> AnyPublisher<Void, Error> {
  79. Future { promise in
  80. self.processQueue.async {
  81. do { func appendPublisher<Value: JSON>(_ newValue: Value, to name: String) -> AnyPublisher<Void, Error> {
  82. Future { promise in
  83. self.processQueue.async {
  84. do {
  85. try self.append(newValue, to: name)
  86. promise(.success(()))
  87. } catch {
  88. promise(.failure(error))
  89. }
  90. }
  91. }
  92. .eraseToAnyPublisher()
  93. }
  94. try self.append(newValue, to: name)
  95. promise(.success(()))
  96. } catch {
  97. promise(.failure(error))
  98. }
  99. }
  100. }
  101. .eraseToAnyPublisher()
  102. }
  103. }