commit e6dfa1b412de26b7115daa13b6bb448ed3aa8859
parent a65f2682814c2a8ed8c148322d959cef226b234b
Author: Marc Stibane <marc@taler.net>
Date: Tue, 2 Sep 2025 16:58:13 +0200
Fix Duration
Diffstat:
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