import Foundation struct Configuration: Codable { let contentFolder: String let trainingIterations: Int let serverPath: String let authenticationToken: String init(at url: URL) throws { guard FileManager.default.fileExists(atPath: url.path) else { print("[ERROR] No configuration at \(url.absoluteURL.path)") throw TrainingError.configurationFileMissing } let data: Data do { data = try Data(contentsOf: url) } catch { print("[ERROR] Failed to load configuration data at \(url.absoluteURL.path): \(error)") throw TrainingError.configurationFileUnreadable } do { self = try JSONDecoder().decode(Configuration.self, from: data) } catch { print("[ERROR] Failed to decode configuration at \(url.absoluteURL.path): \(error)") throw TrainingError.configurationFileDecodingFailed } } func serverUrl() throws -> URL { guard let serverUrl = URL(string: serverPath) else { print("[ERROR] Configuration: Invalid server path \(serverPath)") throw TrainingError.invalidServerPath } return serverUrl } }