field_ios

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

TeraPublicationRetry.swift (3509B)


      1 import Foundation
      2 import TeraKitBindings
      3 
      4 enum TeraPublicationActionReason: Sendable, Equatable {
      5   case coordinateChanged
      6   case deadlineExceeded, attemptLimit, authenticationRequired, quotaExceeded
      7   case invalidPayload, deliveryRefused
      8 
      9   var explanation: String {
     10     switch self {
     11     case .coordinateChanged: "Another request owns this address, the saved timestamp does not win against its known revision, or the clock is behind the captured time. Review the current revision and device clock before publishing. Your captured form and signed evidence are retained."
     12     case .deadlineExceeded: "The saved delivery window does not allow another attempt. The captured form and any signed publication or relay evidence are retained. Review them before choosing another submission."
     13     case .attemptLimit: "The delivery attempt limit was reached. The saved publication and relay evidence are retained for review."
     14     case .authenticationRequired: "A saved relay requires authentication. Review its access requirements before authorizing further publication. This request is retained."
     15     case .quotaExceeded: "A saved relay refused this publication because its quota was exhausted. Review that relay's limits. This request and its recorded effects are retained."
     16     case .invalidPayload: "A saved relay reported a malformed publication. Review the captured form and relay evidence. The original signed publication is retained."
     17     case .deliveryRefused: "A saved relay refused the publication. Review its requirements and the captured form. Recorded remote effects are retained."
     18     }
     19   }
     20 }
     21 
     22 /// Translation and presentation only; Rust decides whether new work may start.
     23 enum TeraPublicationRetry: Sendable, Equatable {
     24   case ready, complete, stopped
     25   case deferredUntil(UInt64), inFlightUntil(UInt64)
     26   case needsAction(TeraPublicationActionReason)
     27 
     28   var mayStart: Bool {
     29     self == .ready
     30   }
     31 
     32   var explanation: String? {
     33     switch self {
     34     case .ready, .complete, .stopped: nil
     35     case let .needsAction(reason): reason.explanation
     36     case let .deferredUntil(at): "The original publication is saved for retry. Check its status after \(date(at))."
     37     case let .inFlightUntil(at): "An original delivery attempt is still claimed. Check its status after \(date(at)); recorded effects remain available."
     38     }
     39   }
     40 
     41   static func decode(_ value: FfiPublicationRetryDecision) throws -> Self {
     42     switch value {
     43     case .ready: .ready
     44     case .complete: .complete
     45     case .stopped: .stopped
     46     case let .deferredUntil(at): try .deferredUntil(timestamp(at))
     47     case let .inFlightUntil(at): try .inFlightUntil(timestamp(at))
     48     case let .needsAction(reason): .needsAction(decode(reason))
     49     }
     50   }
     51 
     52   private static func decode(_ reason: FfiPublicationActionReason) -> TeraPublicationActionReason {
     53     switch reason {
     54     case .coordinateChanged: .coordinateChanged
     55     case .deadlineExceeded: .deadlineExceeded
     56     case .attemptLimit: .attemptLimit
     57     case .authenticationRequired: .authenticationRequired
     58     case .quotaExceeded: .quotaExceeded
     59     case .invalidPayload: .invalidPayload
     60     case .deliveryRefused: .deliveryRefused
     61     }
     62   }
     63 
     64   private static func timestamp(_ value: UInt64) throws -> UInt64 {
     65     guard value > 0, value <= UInt64(Int64.max) else { throw TeraGeneratedSubmission.mismatch() }
     66     return value
     67   }
     68 
     69   private func date(_ value: UInt64) -> String {
     70     Date(timeIntervalSince1970: Double(value) / 1000).formatted(date: .abbreviated, time: .standard)
     71   }
     72 }