field_ios

In-the-field app for Radroots on iOS
git clone https://radroots.dev/git/field_ios.git
Log | Files | Refs | README | LICENSE

TeraUserMessageClassifier.swift (8246B)


      1 import Foundation
      2 import RadrootsKit
      3 
      4 enum TeraUserMessageClassifier {
      5   static func key(
      6     for error: Error,
      7     fallback: TeraUserMessageKey
      8   ) -> TeraUserMessageKey {
      9     runtimeKey(for: error, fallback: fallback)
     10       ?? platformKey(for: error)
     11       ?? identityCustodyKey(for: error)
     12       ?? fallback
     13   }
     14 
     15   private static func runtimeKey(
     16     for error: Error,
     17     fallback: TeraUserMessageKey
     18   ) -> TeraUserMessageKey? {
     19     if error is CancellationError {
     20       return .operationOutcomeUnknown
     21     }
     22     if let error = error as? TeraRuntimeClientError {
     23       return runtimeClientKey(error, fallback: fallback)
     24     }
     25     if let failure = error as? TeraRuntimeFailure {
     26       return failure.messageKey(fallback: fallback)
     27     }
     28     if error is TeraConfigurationError {
     29       return .configurationInvalid
     30     }
     31     if error is TeraIdentityStoreError {
     32       return .identityOperationFailed
     33     }
     34     return nil
     35   }
     36 
     37   private static func identityCustodyKey(for error: Error) -> TeraUserMessageKey? {
     38     error is RadrootsIdentityCustodyError ? .secureStateUnavailable : nil
     39   }
     40 
     41   private static func platformKey(for error: Error) -> TeraUserMessageKey? {
     42     if let error = error as? RadrootsCaptureIntakeError {
     43       return captureKey(error)
     44     }
     45     if let error = error as? RadrootsBackgroundTransferError {
     46       return backgroundTransferKey(error)
     47     }
     48     if let error = error as? RadrootsDocumentInterchangeError {
     49       return documentKey(error)
     50     }
     51     if let error = error as? RadrootsAppLocalStateResetError {
     52       return localStateResetKey(error)
     53     }
     54     if let error = error as? RadrootsAppleMediaPreparationError {
     55       return mediaPreparationKey(error)
     56     }
     57     return secondaryPlatformKey(for: error)
     58   }
     59 
     60   private static func secondaryPlatformKey(
     61     for error: Error
     62   ) -> TeraUserMessageKey? {
     63     if let error = error as? RadrootsTelemetryError {
     64       return telemetryKey(error)
     65     }
     66     if let error = error as? RadrootsExternalActionError {
     67       return externalActionKey(error)
     68     }
     69     if let error = error as? RadrootsAppleFileError {
     70       return fileKey(error)
     71     }
     72     if let error = error as? RadrootsLocationServicesError {
     73       return locationKey(error)
     74     }
     75     if let error = error as? RadrootsUserPresenceError {
     76       return userPresenceKey(error)
     77     }
     78     return tertiaryPlatformKey(for: error)
     79   }
     80 
     81   private static func tertiaryPlatformKey(
     82     for error: Error
     83   ) -> TeraUserMessageKey? {
     84     if let error = error as? RadrootsBackgroundTaskError {
     85       return backgroundTaskKey(error)
     86     }
     87     if let error = error as? RadrootsAppleSecurityError {
     88       return securityKey(error)
     89     }
     90     if let error = error as? RadrootsAppleMobileStoreError {
     91       return mobileStoreKey(error)
     92     }
     93     if let error = error as? RadrootsVerifiedArtifactAccessError {
     94       return verifiedArtifactKey(error)
     95     }
     96     return nil
     97   }
     98 
     99   private static func runtimeClientKey(
    100     _ error: TeraRuntimeClientError,
    101     fallback: TeraUserMessageKey
    102   ) -> TeraUserMessageKey {
    103     switch error {
    104     case .invalidBufferCapacity: .invalidRequest
    105     case .notRunning: .runtimeUnavailable
    106     case .superseded: .operationOutcomeUnknown
    107     case let .startup(failure): failure.messageKey(fallback: .startupFailed)
    108     case let .subscription(failure): failure.messageKey(fallback: .runtimeObservationUnavailable)
    109     case let .shutdown(failure): failure.messageKey(fallback: .shutdownFailed)
    110     case let .status(failure), let .today(failure), let .add(failure), let .support(failure):
    111       failure.messageKey(fallback: fallback)
    112     }
    113   }
    114 
    115   private static func captureKey(
    116     _ error: RadrootsCaptureIntakeError
    117   ) -> TeraUserMessageKey {
    118     switch error {
    119     case .invalidRequest: .invalidRequest
    120     case .spaceInsufficient: .storageFull
    121     case .unavailable: .addMediaUnavailable
    122     case .permissionDenied: .permissionDenied
    123     case .userCancelled: .operationCancelled
    124     case .transientFailure: .tryAgain
    125     case .permanentFailure: .addMediaUnavailable
    126     }
    127   }
    128 
    129   private static func backgroundTransferKey(
    130     _ error: RadrootsBackgroundTransferError
    131   ) -> TeraUserMessageKey {
    132     switch error {
    133     case .invalidRequest: .invalidRequest
    134     case .unavailable: .backgroundTransferUnavailable
    135     case .transferFailure: .backgroundTransferFailed
    136     case .persistenceFailure: .secureStateUnavailable
    137     case .spaceInsufficient: .storageFull
    138     case .receiptCapacityExceeded: .receiptCapacityExceeded
    139     }
    140   }
    141 
    142   private static func documentKey(
    143     _ error: RadrootsDocumentInterchangeError
    144   ) -> TeraUserMessageKey {
    145     switch error {
    146     case .invalidRequest: .invalidRequest
    147     case .notFound: .fileOperationFailed
    148     case .userCancelled: .operationCancelled
    149     case .permissionDenied: .permissionDenied
    150     case .transientFailure: .tryAgain
    151     case .permanentFailure: .fileOperationFailed
    152     }
    153   }
    154 
    155   private static func localStateResetKey(
    156     _ error: RadrootsAppLocalStateResetError
    157   ) -> TeraUserMessageKey {
    158     switch error {
    159     case .invalidRequest: .invalidRequest
    160     case .fileSystemFailure, .keychainFailure: .secureStateUnavailable
    161     }
    162   }
    163 
    164   private static func mediaPreparationKey(
    165     _ error: RadrootsAppleMediaPreparationError
    166   ) -> TeraUserMessageKey {
    167     switch error {
    168     case .invalidRequest: .invalidRequest
    169     case .unavailable, .preparationFailure: .addMediaUnavailable
    170     }
    171   }
    172 
    173   private static func telemetryKey(
    174     _ error: RadrootsTelemetryError
    175   ) -> TeraUserMessageKey {
    176     switch error {
    177     case .invalidRequest: .invalidRequest
    178     }
    179   }
    180 
    181   private static func externalActionKey(
    182     _ error: RadrootsExternalActionError
    183   ) -> TeraUserMessageKey {
    184     switch error {
    185     case .invalidRequest: .invalidRequest
    186     case .blockedByPolicy, .unavailable: .permissionDenied
    187     case .transientFailure: .tryAgain
    188     case .permanentFailure: .runtimeOperationFailed
    189     }
    190   }
    191 
    192   private static func fileKey(
    193     _ error: RadrootsAppleFileError
    194   ) -> TeraUserMessageKey {
    195     switch error {
    196     case .spaceInsufficient: .storageFull
    197     case .invalidRequest: .invalidRequest
    198     case .notFound, .permanentFailure: .fileOperationFailed
    199     case .permissionDenied: .permissionDenied
    200     case .transientFailure: .tryAgain
    201     }
    202   }
    203 
    204   private static func locationKey(
    205     _ error: RadrootsLocationServicesError
    206   ) -> TeraUserMessageKey {
    207     switch error {
    208     case .invalidRequest: .invalidRequest
    209     case .permissionDenied: .permissionDenied
    210     case .unavailable, .timeout, .cancelled, .transientFailure, .permanentFailure:
    211       .locationUnavailable
    212     }
    213   }
    214 
    215   private static func userPresenceKey(
    216     _ error: RadrootsUserPresenceError
    217   ) -> TeraUserMessageKey {
    218     switch error {
    219     case .invalidRequest: .invalidRequest
    220     case .userCancelled: .operationCancelled
    221     case .permissionDenied: .permissionDenied
    222     case .unavailable, .timeout, .transientFailure, .permanentFailure:
    223       .userPresenceUnavailable
    224     }
    225   }
    226 
    227   private static func backgroundTaskKey(
    228     _ error: RadrootsBackgroundTaskError
    229   ) -> TeraUserMessageKey {
    230     switch error {
    231     case .invalidRequest: .invalidRequest
    232     case .unavailable, .schedulerFailure: .runtimeUnavailable
    233     }
    234   }
    235 
    236   private static func securityKey(
    237     _ error: RadrootsAppleSecurityError
    238   ) -> TeraUserMessageKey {
    239     switch error {
    240     case .invalidRequest: .invalidRequest
    241     case .permissionDenied: .permissionDenied
    242     case .userCancelled: .operationCancelled
    243     case .notFound, .transientFailure, .unavailable, .permanentFailure,
    244          .keychainFailure:
    245       .secureStateUnavailable
    246     }
    247   }
    248 
    249   private static func mobileStoreKey(
    250     _ error: RadrootsAppleMobileStoreError
    251   ) -> TeraUserMessageKey {
    252     switch error {
    253     case .invalidPublicKey: .invalidRequest
    254     case .protectedDataUnavailable, .invalidDirectoryLayout, .fileSystemFailure:
    255       .secureStateUnavailable
    256     }
    257   }
    258 
    259   private static func verifiedArtifactKey(
    260     _ error: RadrootsVerifiedArtifactAccessError
    261   ) -> TeraUserMessageKey {
    262     switch error {
    263     case .invalidDescriptor: .invalidRequest
    264     case .protectedDataUnavailable: .secureStateUnavailable
    265     case .artifactUnavailable, .artifactCorrupt, .fileSystemFailure:
    266       .fileOperationFailed
    267     }
    268   }
    269 }