mirror of
				https://github.com/GayPizzaSpecifications/darwin-apk.git
				synced 2025-11-04 07:59:38 +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,13 +150,13 @@ 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