Skip to content

Instantly share code, notes, and snippets.

@mcritz
Created December 2, 2021 22:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcritz/62325b72638e37b3b84d0b7f65ac669e to your computer and use it in GitHub Desktop.
Save mcritz/62325b72638e37b3b84d0b7f65ac669e to your computer and use it in GitHub Desktop.
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