apple_kit

Apple-native services for Radroots iOS and macOS apps
git clone https://radroots.dev/git/apple_kit.git
Log | Files | Refs | README | LICENSE

RadrootsBackgroundTransferValues.swift (4651B)


      1 import Foundation
      2 
      3 public struct RadrootsBackgroundDownloadedArtifact: Sendable, Equatable, Hashable, Codable,
      4     CustomDebugStringConvertible {
      5     public let file: RadrootsFileReference
      6     public let sha256: String
      7     public let byteSize: UInt64
      8     public let mediaType: String?
      9 
     10     public init(file: RadrootsFileReference, sha256: String, byteSize: UInt64, mediaType: String?)
     11         throws {
     12         guard sha256.range(of: "^[0-9a-f]{64}$", options: .regularExpression) != nil, byteSize > 0,
     13               byteSize <= RadrootsBackgroundTransferRequest.absoluteMaximumTransferBytes
     14         else {
     15             throw RadrootsBackgroundTransferError.invalidRequest
     16         }
     17         try RadrootsBackgroundTransferValidation.validateLocalFile(.file(file))
     18         self.file = file
     19         self.sha256 = sha256
     20         self.byteSize = byteSize
     21         self.mediaType = try mediaType.map {
     22             try RadrootsBackgroundTransferValidation.normalizedMediaType($0)
     23         }
     24     }
     25 
     26     public var debugDescription: String {
     27         "RadrootsBackgroundDownloadedArtifact(sha256: \(sha256), byteSize: \(byteSize), "
     28             + "mediaType: \(mediaType ?? "none"), file: <redacted>)"
     29     }
     30 }
     31 
     32 public enum RadrootsBackgroundTransferVerification: Sendable, Equatable {
     33     case accepted
     34     case rejected(failure: RadrootsBackgroundTransferFailure)
     35 }
     36 
     37 public struct RadrootsBackgroundTransferHandle: Sendable, Equatable, Hashable, Codable,
     38     CustomDebugStringConvertible {
     39     public let identifier: RadrootsBackgroundTransferIdentifier
     40     public let request: RadrootsBackgroundTransferRequest
     41 
     42     public init(request: RadrootsBackgroundTransferRequest) {
     43         identifier = request.identifier
     44         self.request = request
     45     }
     46 
     47     public var debugDescription: String {
     48         "RadrootsBackgroundTransferHandle(identifier: \(identifier.rawValue), request: \(request.debugDescription))"
     49     }
     50 
     51     private enum CodingKeys: String, CodingKey {
     52         case identifier
     53         case request
     54     }
     55 
     56     public init(from decoder: any Decoder) throws {
     57         let values = try decoder.container(keyedBy: CodingKeys.self)
     58         let identifier = try values.decode(
     59             RadrootsBackgroundTransferIdentifier.self, forKey: .identifier
     60         )
     61         let request = try values.decode(RadrootsBackgroundTransferRequest.self, forKey: .request)
     62         guard identifier == request.identifier else {
     63             throw RadrootsBackgroundTransferError.invalidRequest
     64         }
     65         self.init(request: request)
     66     }
     67 
     68     public func encode(to encoder: any Encoder) throws {
     69         var values = encoder.container(keyedBy: CodingKeys.self)
     70         try values.encode(identifier, forKey: .identifier)
     71         try values.encode(request, forKey: .request)
     72     }
     73 }
     74 
     75 public struct RadrootsBackgroundTransferProgress: Sendable, Equatable, Hashable, Codable {
     76     public let bytesTransferred: Int64
     77     public let totalBytesExpected: Int64?
     78 
     79     public init(bytesTransferred: Int64, totalBytesExpected: Int64? = nil) throws {
     80         guard bytesTransferred >= 0 else {
     81             throw RadrootsBackgroundTransferError.invalidRequest
     82         }
     83         if let totalBytesExpected {
     84             guard totalBytesExpected >= 0 else {
     85                 throw RadrootsBackgroundTransferError.invalidRequest
     86             }
     87             guard totalBytesExpected >= bytesTransferred else {
     88                 throw RadrootsBackgroundTransferError.invalidRequest
     89             }
     90         }
     91         self.bytesTransferred = bytesTransferred
     92         self.totalBytesExpected = totalBytesExpected
     93     }
     94 
     95     public static let zero = RadrootsBackgroundTransferProgress(
     96         validatedBytesTransferred: 0, totalBytesExpected: nil
     97     )
     98 
     99     private init(validatedBytesTransferred: Int64, totalBytesExpected: Int64?) {
    100         bytesTransferred = validatedBytesTransferred
    101         self.totalBytesExpected = totalBytesExpected
    102     }
    103 
    104     private enum CodingKeys: String, CodingKey {
    105         case bytesTransferred
    106         case totalBytesExpected
    107     }
    108 
    109     public init(from decoder: any Decoder) throws {
    110         let values = try decoder.container(keyedBy: CodingKeys.self)
    111         try self.init(
    112             bytesTransferred: values.decode(Int64.self, forKey: .bytesTransferred),
    113             totalBytesExpected: values.decodeIfPresent(Int64.self, forKey: .totalBytesExpected)
    114         )
    115     }
    116 
    117     public func encode(to encoder: any Encoder) throws {
    118         var values = encoder.container(keyedBy: CodingKeys.self)
    119         try values.encode(bytesTransferred, forKey: .bytesTransferred)
    120         try values.encodeIfPresent(totalBytesExpected, forKey: .totalBytesExpected)
    121     }
    122 }