taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

commit e6dfa1b412de26b7115daa13b6bb448ed3aa8859
parent a65f2682814c2a8ed8c148322d959cef226b234b
Author: Marc Stibane <marc@taler.net>
Date:   Tue,  2 Sep 2025 16:58:13 +0200

Fix Duration

Diffstat:
MTalerWallet1/Model/Model+Payment.swift | 6+++---
Mtaler-swift/Sources/taler-swift/Time.swift | 51+++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/TalerWallet1/Model/Model+Payment.swift b/TalerWallet1/Model/Model+Payment.swift @@ -175,9 +175,9 @@ struct MerchantContractTerms: Codable { let fulfillmentMessageI18n: String? // Plain text fulfillment message in the merchant's default language let products: [Product]? // Products that are sold in this contract let timestamp: Timestamp // Time when the contract was generated by the merchant - let refundDeadline: Timestamp // Deadline for refunds + let refundDeadline: Timestamp? // Deadline for refunds let payDeadline: Timestamp // Deadline to pay for the contract - let wireTransferDeadline: Timestamp // Deadline for the wire transfer + let wireTransferDeadline: Timestamp?// Deadline for the wire transfer let merchantPub: String // Public key of the merchant let merchantBaseURL: String // Base URL of the merchant's backend let merchant: Merchant @@ -187,7 +187,7 @@ struct MerchantContractTerms: Codable { let deliveryLocation: Location? // Delivery location for (all!) products let deliveryDate: Timestamp? // indicating when the order should be delivered let nonce: String // used to ensure freshness - let autoRefund: String? // TODO: TalerProtocolDuration + let autoRefund: Duration? let extra: Extra? // Extra data, interpreted by the merchant only let minimumAge: Int? diff --git a/taler-swift/Sources/taler-swift/Time.swift b/taler-swift/Sources/taler-swift/Time.swift @@ -201,9 +201,44 @@ extension Date { } // MARK: - /// A duration of time, measured in milliseconds. -public enum Duration: Equatable { - case milliseconds(UInt64) +public enum Duration: Codable, Hashable, Equatable { + case microseconds(UInt64) case forever + + enum CodingKeys: String, CodingKey { + case d_us = "d_us" + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + do { + self = Duration.microseconds(try container.decode(UInt64.self, forKey: .d_us)) + } catch { // rethrows or never + let stringValue = try container.decode(String.self, forKey: .d_us) + if stringValue == "forever" { + self = Duration.forever + } else { + throw TimestampError.invalidStringRepresentation + } + } + } + public func hash(into hasher: inout Hasher) { + switch self { + case .microseconds(let d_us): + hasher.combine(d_us) + case .forever: + hasher.combine("forever") + } + } + public func encode(to encoder: Encoder) throws { + var value = encoder.container(keyedBy: CodingKeys.self) + switch self { + case .microseconds(let d_us): + try value.encode(d_us, forKey: .d_us) + case .forever: + try value.encode("forever", forKey: .d_us) + } + } } /// Addition of a timestamp and a duration. @@ -211,8 +246,8 @@ public func +(lhs: Timestamp, rhs: Duration) -> Timestamp { switch lhs { case .milliseconds(let lhs_ms): switch rhs { - case .milliseconds(let rhs_ms): - let result = lhs_ms.addingReportingOverflow(rhs_ms) + case .microseconds(let rhs_us): + let result = lhs_ms.addingReportingOverflow(rhs_us * 1000) if result.overflow { return Timestamp.never } else { @@ -231,8 +266,8 @@ public func -(lhs: Timestamp, rhs: Duration) -> Timestamp { switch lhs { case .milliseconds(let lhs_ms): switch rhs { - case .milliseconds(let rhs_ms): - let result = lhs_ms.subtractingReportingOverflow(rhs_ms) + case .microseconds(let rhs_us): + let result = lhs_ms.subtractingReportingOverflow(rhs_us * 1000) if result.overflow { return Timestamp.milliseconds(0) } else { @@ -253,9 +288,9 @@ public func -(lhs: Timestamp, rhs: Timestamp) throws -> Duration { switch rhs { case .milliseconds(let rhs_ms): if lhs_ms < rhs_ms { - return Duration.milliseconds(0) + return Duration.microseconds(0) } else { - return Duration.milliseconds(lhs_ms - rhs_ms) + return Duration.microseconds((lhs_ms - rhs_ms) * 1000) } case .never: throw TimestampError.invalidArithmeticArguments