FileStorage.swift 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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 appendPublisher<Value: JSON>(_: Value, to name: String) -> AnyPublisher<Void, Error>
  11. }
  12. final class BaseFileStorage: FileStorage {
  13. private let processQueue = DispatchQueue(label: "BaseFileStorage.processQueue")
  14. func save<Value: JSON>(_ value: Value, as name: String) throws {
  15. let encoder = JSONEncoder()
  16. encoder.outputFormatting = .prettyPrinted
  17. try Disk.save(value, to: .documents, as: name, encoder: encoder)
  18. }
  19. func savePublisher<Value: JSON>(_ value: Value, as name: String) -> AnyPublisher<Void, Error> {
  20. Future { promise in
  21. self.processQueue.async {
  22. do {
  23. try self.save(value, as: name)
  24. promise(.success(()))
  25. } catch {
  26. promise(.failure(error))
  27. }
  28. }
  29. }
  30. .eraseToAnyPublisher()
  31. }
  32. func retrieve<Value: JSON>(_ name: String, as type: Value.Type) throws -> Value {
  33. try Disk.retrieve(name, from: .documents, as: type)
  34. }
  35. func retrievePublisher<Value: JSON>(_ name: String, as type: Value.Type) -> AnyPublisher<Value, Error> {
  36. Future { promise in
  37. self.processQueue.async {
  38. do {
  39. let value = try self.retrieve(name, as: type)
  40. promise(.success(value))
  41. } catch {
  42. promise(.failure(error))
  43. }
  44. }
  45. }
  46. .eraseToAnyPublisher()
  47. }
  48. func append<Value: JSON>(_ newValue: Value, to name: String) throws {
  49. try Disk.append(newValue, to: name, in: .documents)
  50. }
  51. func appendPublisher<Value: JSON>(_ newValue: Value, to name: String) -> AnyPublisher<Void, Error> {
  52. Future { promise in
  53. self.processQueue.async {
  54. do {
  55. try self.append(newValue, to: name)
  56. promise(.success(()))
  57. } catch {
  58. promise(.failure(error))
  59. }
  60. }
  61. }
  62. .eraseToAnyPublisher()
  63. }
  64. }