mirror of
https://github.com/GayPizzaSpecifications/darwin-apk.git
synced 2025-08-03 13:31:32 +00:00
Improve indexing error messages
This commit is contained in:
@ -3,6 +3,8 @@
|
|||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
public struct ApkIndex: Sendable {
|
public struct ApkIndex: Sendable {
|
||||||
public let packages: [ApkIndexPackage]
|
public let packages: [ApkIndexPackage]
|
||||||
}
|
}
|
||||||
@ -32,9 +34,13 @@ public extension ApkIndex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension ApkIndex {
|
extension ApkIndex {
|
||||||
init(raw: ApkRawIndex) throws {
|
init(raw: ApkRawIndex) throws(ApkIndexError) {
|
||||||
self.packages = try raw.packages.map {
|
self.packages = try raw.packages.map { records throws(ApkIndexError) in
|
||||||
try ApkIndexPackage(raw: $0)
|
do {
|
||||||
|
return try ApkIndexPackage(raw: records)
|
||||||
|
} catch {
|
||||||
|
throw .parseError(records.lookup("P") ?? "UNKNOWN", error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,3 +50,16 @@ extension ApkIndex: CustomStringConvertible {
|
|||||||
self.packages.map(String.init).joined(separator: "\n")
|
self.packages.map(String.init).joined(separator: "\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ApkIndexError: Error {
|
||||||
|
case parseError(String, any Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ApkIndexError: LocalizedError {
|
||||||
|
public var errorDescription: String? {
|
||||||
|
switch self {
|
||||||
|
case .parseError(let packageName, let cause):
|
||||||
|
return "Failed to parse index for \"\(packageName)\": \(cause.localizedDescription)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -74,32 +74,32 @@ extension ApkIndexPackage {
|
|||||||
do {
|
do {
|
||||||
dependencies = try record.value.split(separator: " ")
|
dependencies = try record.value.split(separator: " ")
|
||||||
.map { .init(requirement: try .init(extract: $0)) }
|
.map { .init(requirement: try .init(extract: $0)) }
|
||||||
} catch { throw .badValue(key: record.key) }
|
} catch { throw .badValue(key: record.key, cause: error.localizedDescription) }
|
||||||
case "C":
|
case "C":
|
||||||
guard let digest = ApkIndexDigest(decode: record.value) else {
|
guard let digest = ApkIndexDigest(decode: record.value) else {
|
||||||
throw .badValue(key: record.key)
|
throw .badValue(key: record.key, cause: "Invalid SHA digest")
|
||||||
}
|
}
|
||||||
indexChecksum = digest
|
indexChecksum = digest
|
||||||
case "S":
|
case "S":
|
||||||
guard let value = UInt64(record.value, radix: 10) else {
|
guard let value = UInt64(record.value, radix: 10) else {
|
||||||
throw .badValue(key: record.key)
|
throw .badValue(key: record.key, cause: "Invalid size value")
|
||||||
}
|
}
|
||||||
packageSize = value
|
packageSize = value
|
||||||
case "I":
|
case "I":
|
||||||
guard let value = UInt64(record.value, radix: 10) else {
|
guard let value = UInt64(record.value, radix: 10) else {
|
||||||
throw .badValue(key: record.key)
|
throw .badValue(key: record.key, cause: "Invalid installed size value")
|
||||||
}
|
}
|
||||||
installedSize = value
|
installedSize = value
|
||||||
case "p":
|
case "p":
|
||||||
do {
|
do {
|
||||||
provides = try record.value.split(separator: " ")
|
provides = try record.value.split(separator: " ")
|
||||||
.map { .init(requirement: try .init(extract: $0)) }
|
.map { .init(requirement: try .init(extract: $0)) }
|
||||||
} catch { throw .badValue(key: record.key) }
|
} catch { throw .badValue(key: record.key, cause: error.localizedDescription) }
|
||||||
case "i":
|
case "i":
|
||||||
do {
|
do {
|
||||||
installIf = try record.value.split(separator: " ")
|
installIf = try record.value.split(separator: " ")
|
||||||
.map { .init(requirement: try .init(extract: $0)) }
|
.map { .init(requirement: try .init(extract: $0)) }
|
||||||
} catch { throw .badValue(key: record.key) }
|
} catch { throw .badValue(key: record.key, cause: error.localizedDescription) }
|
||||||
case "o":
|
case "o":
|
||||||
origin = record.value
|
origin = record.value
|
||||||
case "m":
|
case "m":
|
||||||
@ -107,7 +107,7 @@ extension ApkIndexPackage {
|
|||||||
case "t":
|
case "t":
|
||||||
guard let timet = UInt64(record.value, radix: 10),
|
guard let timet = UInt64(record.value, radix: 10),
|
||||||
let timetInterval = TimeInterval(exactly: timet) else {
|
let timetInterval = TimeInterval(exactly: timet) else {
|
||||||
throw .badValue(key: record.key)
|
throw .badValue(key: record.key, cause: "Invalid build time value")
|
||||||
}
|
}
|
||||||
buildTime = Date(timeIntervalSince1970: timetInterval)
|
buildTime = Date(timeIntervalSince1970: timetInterval)
|
||||||
case "c":
|
case "c":
|
||||||
@ -115,7 +115,7 @@ extension ApkIndexPackage {
|
|||||||
case "k":
|
case "k":
|
||||||
guard let value = UInt64(record.value, radix: 10),
|
guard let value = UInt64(record.value, radix: 10),
|
||||||
(0..<UInt64(UInt16.max)).contains(value) else {
|
(0..<UInt64(UInt16.max)).contains(value) else {
|
||||||
throw .badValue(key: record.key)
|
throw .badValue(key: record.key, cause: "Invalid provider priority value")
|
||||||
}
|
}
|
||||||
providerPriority = UInt16(truncatingIfNeeded: value)
|
providerPriority = UInt16(truncatingIfNeeded: value)
|
||||||
case "F", "M", "R", "Z", "r", "q", "a", "s", "f":
|
case "F", "M", "R", "Z", "r", "q", "a", "s", "f":
|
||||||
@ -123,7 +123,7 @@ extension ApkIndexPackage {
|
|||||||
default:
|
default:
|
||||||
// Safe to ignore
|
// Safe to ignore
|
||||||
guard record.key.isLowercase else {
|
guard record.key.isLowercase else {
|
||||||
throw .badValue(key: record.key)
|
throw .unexpectedKey(key: record.key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,15 +150,15 @@ extension ApkIndexPackage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum ParseError: Error, LocalizedError {
|
public enum ParseError: Error, LocalizedError {
|
||||||
case badValue(key: Character)
|
case badValue(key: Character, cause: String)
|
||||||
case unexpectedKey(key: Character)
|
case unexpectedKey(key: Character)
|
||||||
case required(key: Character)
|
case required(key: Character)
|
||||||
|
|
||||||
public var errorDescription: String? {
|
public var errorDescription: String? {
|
||||||
switch self {
|
switch self {
|
||||||
case .badValue(let key): "Bad value for key \"\(key)\""
|
case .badValue(let key, let cause): "Bad value for key \"\(key)\": \(cause)"
|
||||||
case .unexpectedKey(let key): "Unexpected key \"\(key)\""
|
case .unexpectedKey(let key): "Unexpected key \"\(key)\""
|
||||||
case .required(let key): "Missing required key \"\(key)\""
|
case .required(let key): "Missing required key \"\(key)\""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user