/* * darwin-apk © 2024 Gay Pizza Specifications * SPDX-License-Identifier: Apache-2.0 */ import Foundation struct ApkIndexPackage: ApkIndexRequirementRef { let indexChecksum: ApkIndexDigest let name: String let version: String let architecture: String? let packageSize: UInt64 let installedSize: UInt64 let packageDescription: String let url: String let license: String let origin: String? let maintainer: String? let buildTime: Date? let commit: String? let providerPriority: UInt16? let dependencies: [ApkIndexDependency] let provides: [ApkIndexProvides] let installIf: [ApkIndexInstallIf] var downloadFilename: String { "\(self.name)-\(version).apk" } //TODO: Implementation //lazy var semanticVersion: (Int, Int, Int) = (0, 0, 0) init(name: String, version spec: ApkVersionSpecification) { fatalError("Cannot construct an ApkIndexPackage this way") } } extension ApkIndexPackage { init(raw rawEntry: ApkRawIndexEntry) throws(Self.ParseError) { // Required fields var indexChecksum: ApkIndexDigest? = nil var name: String? = nil var version: String? = nil var description: String? = nil var url: String? = nil var license: String? = nil var packageSize: UInt64? = nil var installedSize: UInt64? = nil var dependencies = [ApkIndexDependency]() var provides = [ApkIndexProvides]() var installIf = [ApkIndexInstallIf]() // Optional fields var architecture: String? = nil var origin: String? = nil var maintainer: String? = nil var buildTime: Date? = nil var commit: String? = nil var providerPriority: UInt16? = nil // Read all the raw records for this entry for record in rawEntry.fields { switch record.key { case "P": name = record.value case "V": version = record.value case "T": description = record.value case "U": url = record.value case "L": license = record.value case "A": architecture = record.value case "D": do { dependencies = try ApkIndexDependency.extract(record.value) } catch { throw .badValue(key: record.key) } case "C": guard let digest = ApkIndexDigest(decode: record.value) else { throw .badValue(key: record.key) } indexChecksum = digest case "S": guard let value = UInt64(record.value, radix: 10) else { throw .badValue(key: record.key) } packageSize = value case "I": guard let value = UInt64(record.value, radix: 10) else { throw .badValue(key: record.key) } installedSize = value case "p": do { provides = try ApkIndexProvides.extract(record.value) } catch { throw .badValue(key: record.key) } case "i": do { installIf = try ApkIndexInstallIf.extract(record.value) } catch { throw .badValue(key: record.key) } case "o": origin = record.value case "m": maintainer = record.value case "t": guard let timet = UInt64(record.value, radix: 10), let timetInterval = TimeInterval(exactly: timet) else { throw .badValue(key: record.key) } buildTime = Date(timeIntervalSince1970: timetInterval) case "c": commit = record.value case "k": guard let value = UInt64(record.value, radix: 10), (0..(or error: @autoclosure () -> E) throws(E) -> Wrapped { switch self { case .some(let v): return v case .none: throw error() } } }