Files
darwin-apk/Sources/apk/Index/ApkIndexDownloader.swift

54 lines
1.8 KiB
Swift

/*
* darwin-apk © 2024 Gay Pizza Specifications
* SPDX-License-Identifier: Apache-2.0
*/
import Foundation
public struct ApkIndexDownloader {
public static func fetch(repository: ApkIndexRepository) async throws(FetchError) -> URL {
let localDestinationURL = URL(filePath: repository.localName)
let tempLocationURL: URL, response: URLResponse
do {
(tempLocationURL, response) = try await URLSession.shared.download(from: repository.url)
} catch {
throw .downloadFailed(error)
}
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw .invalidServerResponse((response as? HTTPURLResponse)?.statusCode ?? -1)
}
// Move index repository to destination location
do {
// Replace existing APKINDEX.tar.gz files
if FileManager.default.fileExists(atPath: localDestinationURL.path()) {
try FileManager.default.removeItem(at: localDestinationURL)
}
// Move downloaded file to the new location
try FileManager.default.moveItem(at: tempLocationURL, to: localDestinationURL)
return localDestinationURL
} catch let error {
throw .moveFailed(error)
}
}
}
public extension ApkIndexDownloader {
enum FetchError: Error, LocalizedError {
case invalidServerResponse(_ code: Int)
case downloadFailed(_ err: any Error)
case moveFailed(_ err: any Error)
public var errorDescription: String? {
switch self {
case .invalidServerResponse(let code): "Server responded with HTTP response code \(code)"
case .downloadFailed(let err): "Failed to create session, \(err.localizedDescription)"
case .moveFailed(let err): "Couldn't move index, \(err.localizedDescription)"
}
}
}
}