|
// |
|
// AuthorsDataStore.swift |
|
// Reading Journal |
|
// |
|
// |
|
|
|
import SwiftUI |
|
|
|
final class AuthorsDataStore: SingleInstanceDataStore { |
|
typealias Fetcher = AuthorsDataFetcher |
|
static let Enum = DataType.authors |
|
|
|
// Instance variables that need to be initialized |
|
@Published |
|
private var user: MUser |
|
|
|
private init(user: MUser) { |
|
self.user = user |
|
} |
|
|
|
// Other instance variables |
|
@Published |
|
private(set) var authors: [MAuthor] = [] |
|
|
|
// Static variables |
|
private static let LOG = Tools.getLogger(filename: #file) |
|
} |
|
|
|
// MARK: Implementing DataStore Protocol Methods |
|
|
|
extension AuthorsDataStore { |
|
private static var INSTANCE: AuthorsDataStore? |
|
|
|
static func shared(_ user: MUser) -> Self { |
|
if INSTANCE == nil { |
|
INSTANCE = AuthorsDataStore(user: user) |
|
} |
|
return INSTANCE! as! Self |
|
} |
|
|
|
static func flush() { |
|
LOG.info("Flushing \(String(describing: self))", #line) |
|
INSTANCE = nil |
|
} |
|
|
|
func seed(_ seeding: DataStoreSeeding) { |
|
switch seeding { |
|
case let .author(author): |
|
add(author: author) |
|
default: () |
|
} |
|
} |
|
} |
|
|
|
// MARK: Product Accessors |
|
|
|
extension AuthorsDataStore { |
|
func by(id: String) -> MAuthor? { |
|
authors.first { $0.id == id } |
|
} |
|
|
|
/// Returns whether there exists an author with the given name |
|
/// - Parameter name: Author's name to check |
|
/// - Returns: `true` if an author with a matching name exists in this data store |
|
func exists(with name: String) -> Bool { |
|
authors.contains { |
|
$0.name.lowercased() == name.lowercased() |
|
} |
|
} |
|
} |
|
|
|
// MARK: Fetcher Accessors |
|
|
|
// Product shouldn't call these methods directly. |
|
|
|
extension AuthorsDataStore { |
|
func add(author: MAuthor) { |
|
withAnimation(.easeInOut(speed: .xFast)) { |
|
addImpl(author: author) |
|
} |
|
} |
|
|
|
func add(authors: [MAuthor]) { |
|
withAnimation(.easeInOut(speed: .xFast)) { |
|
authors.forEach { addImpl(author: $0) } |
|
} |
|
} |
|
|
|
func update(author: MAuthor) { |
|
withAnimation(.easeInOut(speed: .xFast)) { |
|
updateImpl(author: author) |
|
} |
|
} |
|
|
|
func remove(author: MAuthor) { |
|
withAnimation(.easeInOut(speed: .xFast)) { |
|
authors.removeAll { $0.id == author.id } |
|
} |
|
} |
|
} |
|
|
|
// MARK: Private Methods |
|
|
|
extension AuthorsDataStore { |
|
private func addImpl(author: MAuthor) { |
|
sortAfter { |
|
if by(id: author.id) != nil { |
|
updateImpl(author: author) |
|
return |
|
} |
|
authors.append(author) |
|
} |
|
} |
|
|
|
private func updateImpl(author: MAuthor) { |
|
sortAfter { |
|
guard let index = firstIndexOf(author) else { |
|
return |
|
} |
|
authors[index] = author |
|
} |
|
} |
|
|
|
private func firstIndexOf(_ author: MAuthor) -> Int? { |
|
authors.firstIndex { $0.id == author.id } |
|
} |
|
|
|
private func sortAfter(callable: () -> Void) { |
|
callable() |
|
authors.sort(using: MAuthor.nameComparator()) |
|
} |
|
} |