Created
December 2, 2021 22:16
-
-
Save mcritz/62325b72638e37b3b84d0b7f65ac669e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
enum StoredObject: Codable { | |
case all(groups: [InterestGroup]?) | |
case selected(group: InterestGroup?) | |
case events(groupID: UUID, events: [Event]?) | |
func url(root url: URL) -> URL { | |
switch self { | |
case .all: | |
return url.appendingPathComponent("InteresteGroups.json") | |
case .selected: | |
return url.appendingPathComponent("SelectedInterestGroup.json") | |
case .events(let uuid, _): | |
return url.appendingPathComponent("Events-\(uuid.uuidString).json") | |
} | |
} | |
} | |
protocol CoffeeStore { | |
associatedtype StoredType | |
func save(_ stored: StoredObject) async throws | |
func load(_ stored: StoredObject) async throws -> StoredObject | |
} | |
struct AsyncFileCoffeeStore<StoredType: Codable>: CoffeeStore { | |
private let rootDirectoryURL: URL | |
init(_ url: URL) { | |
self.rootDirectoryURL = url | |
} | |
private func save<T: Codable>(_ object: T, at url: URL) async throws { | |
Task(priority: .userInitiated) { | |
try JSONEncoder().encode(object).write(to: url) | |
} | |
} | |
private func load<T: Decodable>(_ type: T.Type, at url: URL) async throws -> T { | |
return try await Task(priority: .userInitiated) { | |
let data = try Data(contentsOf: url) | |
return try JSONDecoder().decode(type, from: data) | |
} | |
.value | |
} | |
func load(_ stored: StoredObject) async throws -> StoredObject { | |
switch stored { | |
case .all: | |
async let groups = load([InterestGroup].self, | |
at: stored.url(root: rootDirectoryURL)) | |
return try await .all(groups: groups) | |
case .selected: | |
async let selected = load(InterestGroup.self, | |
at: stored.url(root: rootDirectoryURL)) | |
return try await .selected(group: selected) | |
case .events(let uuid, _): | |
async let loadedEvents = load([Event].self, | |
at: stored.url(root: rootDirectoryURL)) | |
return try await .events(groupID: uuid, events: loadedEvents) | |
} | |
} | |
func save(_ stored: StoredObject) async throws { | |
switch stored { | |
case .all(groups: let groups): | |
try await save(groups, at: stored.url(root: rootDirectoryURL)) | |
case .selected(group: let group): | |
try await save(group, at: stored.url(root: rootDirectoryURL)) | |
case .events(_, events: let events): | |
try await save(events, at: stored.url(root: rootDirectoryURL)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment