Files
Amphlify/Packages/AmphlifyKit/Sources/SourceFake/FakeSource.swift
T

76 lines
2.8 KiB
Swift

import Domain
import Foundation
import Synchronization
public final class FakeSource: LibrarySource, Starring, LyricsSource {
public let id: SourceID
public let name: String
private let catalog: FakeCatalog
private let artworkDirectory: URL
private struct Extras {
var changes: [Change] = []
var artwork: [String: URL] = [:]
var lyrics: [String: URL] = [:]
}
private let extras = Mutex(Extras())
public init(id: SourceID = SourceID(), name: String = "Demo Library") {
self.id = id
self.name = name
catalog = FakeCatalog(source: id)
artworkDirectory = FileManager.default.temporaryDirectory.appending(path: "FakeSourceArtwork", directoryHint: .isDirectory)
try? FileManager.default.createDirectory(at: artworkDirectory, withIntermediateDirectories: true)
}
public var sampleTracks: [Track] {
catalog.changes.compactMap {
if case let .upsert(.track(track)) = $0 {
return track
}
return nil
}
}
public func add(_ changes: [Change], artworkFiles: [String: URL], lyricsFiles: [String: URL] = [:]) {
extras.withLock {
$0.changes += changes
$0.artwork.merge(artworkFiles) { $1 }
$0.lyrics.merge(lyricsFiles) { $1 }
}
}
public func lyrics(for track: EntityID) async throws -> Lyrics? {
guard let file = extras.withLock({ $0.lyrics[track.remote] }) else { return nil }
return try Lyrics(lrc: String(contentsOf: file, encoding: .utf8))
}
public func changes(since cursor: Cursor?) -> AsyncThrowingStream<Change, Error> {
let changes = cursor == nil ? catalog.changes + extras.withLock(\.changes) : []
return AsyncThrowingStream { continuation in
changes.forEach { continuation.yield($0) }
continuation.yield(.checkpoint(Cursor("1")))
continuation.finish()
}
}
public func stream(for _: EntityID) async throws -> StreamRequest {
throw SourceError.notFound
}
public func artwork(_ id: EntityID, pixelSize: Int) async throws -> ResourceRequest {
if let file = extras.withLock({ $0.artwork[id.remote] }) {
return ResourceRequest(url: file)
}
let side = pixelSize <= 320 ? 320 : 1024
let file = artworkDirectory.appending(path: "\(id.remote)-\(side).png")
if !FileManager.default.fileExists(atPath: file.path) {
guard let data = FakeArtwork.png(seed: id.remote, side: side) else { throw SourceError.notFound }
try data.write(to: file, options: .atomic)
}
return ResourceRequest(url: file)
}
public func setFavorite(_: Bool, for _: EntityID, kind _: EntityKind) async throws {}
}