// // TankCatalogLoader.swift // GasTankAR // // Created by Dennis Nemec on 14.09.26. // import Foundation /// Rohdaten des Tank-Katalogs, wie sie in `Tanks.json` abgelegt sind: die /// verfügbaren Varianten sowie die separat gepflegten Anzeigenamen-Mappings /// (jeweils `rawValue` → Anzeigename). nonisolated struct TankCatalogFile: Decodable { let sizeDisplayNames: [String: String] let colorDisplayNames: [String: String] let tanks: [TankDefinition] } /// Lädt den Tank-Katalog aus einer JSON-Quelle. Über das Protokoll lässt sich /// die Quelle für Tests austauschen (z. B. In-Memory-Daten). nonisolated protocol TankCatalogLoading { func load() throws -> TankCatalogFile } nonisolated enum TankCatalogLoaderError: Error, Equatable { /// Die JSON-Ressource wurde im Bundle nicht gefunden. case resourceNotFound(name: String, extension: String) } /// Lädt den Katalog aus einer JSON-Datei im App-Bundle. nonisolated struct BundleTankCatalogLoader: TankCatalogLoading { let bundle: Bundle let resourceName: String let resourceExtension: String init(bundle: Bundle = .main, resourceName: String = "Tanks", resourceExtension: String = "json") { self.bundle = bundle self.resourceName = resourceName self.resourceExtension = resourceExtension } func load() throws -> TankCatalogFile { guard let url = bundle.url(forResource: resourceName, withExtension: resourceExtension) else { throw TankCatalogLoaderError.resourceNotFound(name: resourceName, extension: resourceExtension) } let data = try Data(contentsOf: url) return try JSONDecoder().decode(TankCatalogFile.self, from: data) } } /// Lädt den Katalog aus bereits vorliegenden JSON-Daten (nützlich für Tests). nonisolated struct DataTankCatalogLoader: TankCatalogLoading { let data: Data func load() throws -> TankCatalogFile { try JSONDecoder().decode(TankCatalogFile.self, from: data) } }