From 562332f386697bcdde28e81b77bcef2ca1f205c0 Mon Sep 17 00:00:00 2001 From: Dariusz Rybicki <dariusz@elixxir.io> Date: Fri, 22 Jul 2022 11:42:19 +0100 Subject: [PATCH] Add CmixWaitForMessageDelivery functor --- Sources/ElixxirDAppsSDK/Cmix.swift | 7 +- .../CmixWaitForMessageDelivery.swift | 32 +++++++++ .../Legacy/MessageDeliveryWaiter.swift | 71 ------------------- .../MessageDeliveryCallback.swift | 58 +++++++++++++++ .../{Legacy => }/MessageSendReport.swift | 8 +++ 5 files changed, 103 insertions(+), 73 deletions(-) create mode 100644 Sources/ElixxirDAppsSDK/CmixWaitForMessageDelivery.swift delete mode 100644 Sources/ElixxirDAppsSDK/Legacy/MessageDeliveryWaiter.swift create mode 100644 Sources/ElixxirDAppsSDK/MessageDeliveryCallback.swift rename Sources/ElixxirDAppsSDK/{Legacy => }/MessageSendReport.swift (72%) diff --git a/Sources/ElixxirDAppsSDK/Cmix.swift b/Sources/ElixxirDAppsSDK/Cmix.swift index 327e630c..527f5069 100644 --- a/Sources/ElixxirDAppsSDK/Cmix.swift +++ b/Sources/ElixxirDAppsSDK/Cmix.swift @@ -12,6 +12,7 @@ public struct Cmix { public var waitForNetwork: CmixWaitForNetwork public var registerClientErrorCallback: CmixRegisterClientErrorCallback public var addHealthCallback: CmixAddHealthCallback + public var waitForMessageDelivery: CmixWaitForMessageDelivery } extension Cmix { @@ -27,7 +28,8 @@ extension Cmix { stopNetworkFollower: .live(bindingsCmix), waitForNetwork: .live(bindingsCmix), registerClientErrorCallback: .live(bindingsCmix), - addHealthCallback: .live(bindingsCmix) + addHealthCallback: .live(bindingsCmix), + waitForMessageDelivery: .live(bindingsCmix) ) } } @@ -44,6 +46,7 @@ extension Cmix { stopNetworkFollower: .unimplemented, waitForNetwork: .unimplemented, registerClientErrorCallback: .unimplemented, - addHealthCallback: .unimplemented + addHealthCallback: .unimplemented, + waitForMessageDelivery: .unimplemented ) } diff --git a/Sources/ElixxirDAppsSDK/CmixWaitForMessageDelivery.swift b/Sources/ElixxirDAppsSDK/CmixWaitForMessageDelivery.swift new file mode 100644 index 00000000..e326a279 --- /dev/null +++ b/Sources/ElixxirDAppsSDK/CmixWaitForMessageDelivery.swift @@ -0,0 +1,32 @@ +import Bindings +import XCTestDynamicOverlay + +public struct CmixWaitForMessageDelivery { + public var run: (MessageSendReport, Int, MessageDeliveryCallback) throws -> Void + + public func callAsFunction( + report: MessageSendReport, + timeoutMS: Int, + callback: MessageDeliveryCallback + ) throws { + try run(report, timeoutMS, callback) + } +} + +extension CmixWaitForMessageDelivery { + public static func live(_ bindingsCmix: BindingsCmix) -> CmixWaitForMessageDelivery { + CmixWaitForMessageDelivery { report, timeoutMS, callback in + try bindingsCmix.wait( + forMessageDelivery: try report.encode(), + mdc: callback.makeBindingsMessageDeliveryCallback(), + timeoutMS: timeoutMS + ) + } + } +} + +extension CmixWaitForMessageDelivery { + public static let unimplemented = CmixWaitForMessageDelivery( + run: XCTUnimplemented("\(Self.self)") + ) +} diff --git a/Sources/ElixxirDAppsSDK/Legacy/MessageDeliveryWaiter.swift b/Sources/ElixxirDAppsSDK/Legacy/MessageDeliveryWaiter.swift deleted file mode 100644 index fa6620f2..00000000 --- a/Sources/ElixxirDAppsSDK/Legacy/MessageDeliveryWaiter.swift +++ /dev/null @@ -1,71 +0,0 @@ -import Bindings - -public struct MessageDeliveryWaiter { - public enum Result: Equatable { - case delivered(roundResults: [Int]) - case notDelivered(timedOut: Bool) - } - - public var wait: (MessageSendReport, Int, @escaping (Result) -> Void) throws -> Void - - public func callAsFunction( - report: MessageSendReport, - timeoutMS: Int, - callback: @escaping (Result) -> Void - ) throws { - try wait(report, timeoutMS, callback) - } -} - -extension MessageDeliveryWaiter { - public static func live(bindingsClient: BindingsCmix) -> MessageDeliveryWaiter { - MessageDeliveryWaiter { report, timeoutMS, callback in - let encoder = JSONEncoder() - let reportData = try encoder.encode(report) - try bindingsClient.wait( - forMessageDelivery: reportData, - mdc: Callback(onCallback: callback), - timeoutMS: timeoutMS - ) - } - } -} - -private final class Callback: NSObject, BindingsMessageDeliveryCallbackProtocol { - init(onCallback: @escaping (MessageDeliveryWaiter.Result) -> Void) { - self.onCallback = onCallback - super.init() - } - - let onCallback: (MessageDeliveryWaiter.Result) -> Void - - func eventCallback(_ delivered: Bool, timedOut: Bool, roundResults: Data?) { - if delivered, !timedOut, let roundResultsData = roundResults { - let decoder = JSONDecoder() - do { - let roundResults = try decoder.decode([Int].self, from: roundResultsData) - return onCallback(.delivered(roundResults: roundResults)) - } catch { - return onCallback(.delivered(roundResults: [Int]())) - } - } - if !delivered, roundResults == nil { - return onCallback(.notDelivered(timedOut: timedOut)) - } - fatalError(""" - BindingsMessageDeliveryCallback received invalid parameters: - - delivered → \(delivered) - - timedOut → \(timedOut) - - roundResults == nil → \(roundResults == nil) - """) - } -} - -#if DEBUG -extension MessageDeliveryWaiter { - public static let failing = MessageDeliveryWaiter { _, _, _ in - struct NotImplemented: Error {} - throw NotImplemented() - } -} -#endif diff --git a/Sources/ElixxirDAppsSDK/MessageDeliveryCallback.swift b/Sources/ElixxirDAppsSDK/MessageDeliveryCallback.swift new file mode 100644 index 00000000..329c804c --- /dev/null +++ b/Sources/ElixxirDAppsSDK/MessageDeliveryCallback.swift @@ -0,0 +1,58 @@ +import Bindings +import XCTestDynamicOverlay + +public struct MessageDeliveryCallback { + public enum Result: Equatable { + case delivered(roundResults: [Int]) + case notDelivered(timedOut: Bool) + } + + public init(handle: @escaping (Result) -> Void) { + self.handle = handle + } + + public var handle: (Result) -> Void +} + +extension MessageDeliveryCallback { + public static let unimplemented = MessageDeliveryCallback( + handle: XCTUnimplemented("\(Self.self)") + ) +} + +extension MessageDeliveryCallback { + func makeBindingsMessageDeliveryCallback() -> BindingsMessageDeliveryCallbackProtocol { + class Callback: NSObject, BindingsMessageDeliveryCallbackProtocol { + init(_ callback: MessageDeliveryCallback) { + self.callback = callback + } + + let callback: MessageDeliveryCallback + + func eventCallback(_ delivered: Bool, timedOut: Bool, roundResults: Data?) { + if delivered, + !timedOut, + let roundResultsData = roundResults, + let roundResults = try? JSONDecoder().decode([Int].self, from: roundResultsData) + { + callback.handle(.delivered(roundResults: roundResults)) + return + } + + if !delivered { + callback.handle(.notDelivered(timedOut: timedOut)) + return + } + + fatalError(""" + BindingsMessageDeliveryCallback received invalid parameters: + - delivered → \(delivered) + - timedOut → \(timedOut) + - roundResults → \(roundResults.map { String(data: $0, encoding: .utf8) ?? "" } ?? "") + """) + } + } + + return Callback(self) + } +} diff --git a/Sources/ElixxirDAppsSDK/Legacy/MessageSendReport.swift b/Sources/ElixxirDAppsSDK/MessageSendReport.swift similarity index 72% rename from Sources/ElixxirDAppsSDK/Legacy/MessageSendReport.swift rename to Sources/ElixxirDAppsSDK/MessageSendReport.swift index 60af863f..8ac2038b 100644 --- a/Sources/ElixxirDAppsSDK/Legacy/MessageSendReport.swift +++ b/Sources/ElixxirDAppsSDK/MessageSendReport.swift @@ -22,4 +22,12 @@ extension MessageSendReport: Codable { case messageId = "MessageID" case timestamp = "Timestamp" } + + static func decode(_ data: Data) throws -> MessageSendReport { + try JSONDecoder().decode(Self.self, from: data) + } + + func encode() throws -> Data { + try JSONEncoder().encode(self) + } } -- GitLab