From 58da450456b7eaa1c9a6da2e92fc5293495a6d67 Mon Sep 17 00:00:00 2001
From: Dariusz Rybicki <dariusz@elixxir.io>
Date: Thu, 21 Jul 2022 19:32:22 +0100
Subject: [PATCH] Add client error callback handler

---
 .../{Legacy => }/ClientError.swift            |  0
 .../ElixxirDAppsSDK/ClientErrorCallback.swift | 47 ++++++++++++++++++
 Sources/ElixxirDAppsSDK/Cmix.swift            |  7 ++-
 .../CmixRegisterClientErrorCallback.swift     | 28 +++++++++++
 .../Legacy/ClientErrorListener.swift          | 48 -------------------
 5 files changed, 80 insertions(+), 50 deletions(-)
 rename Sources/ElixxirDAppsSDK/{Legacy => }/ClientError.swift (100%)
 create mode 100644 Sources/ElixxirDAppsSDK/ClientErrorCallback.swift
 create mode 100644 Sources/ElixxirDAppsSDK/CmixRegisterClientErrorCallback.swift
 delete mode 100644 Sources/ElixxirDAppsSDK/Legacy/ClientErrorListener.swift

diff --git a/Sources/ElixxirDAppsSDK/Legacy/ClientError.swift b/Sources/ElixxirDAppsSDK/ClientError.swift
similarity index 100%
rename from Sources/ElixxirDAppsSDK/Legacy/ClientError.swift
rename to Sources/ElixxirDAppsSDK/ClientError.swift
diff --git a/Sources/ElixxirDAppsSDK/ClientErrorCallback.swift b/Sources/ElixxirDAppsSDK/ClientErrorCallback.swift
new file mode 100644
index 00000000..065a243e
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/ClientErrorCallback.swift
@@ -0,0 +1,47 @@
+import Bindings
+import XCTestDynamicOverlay
+
+public struct ClientErrorCallback {
+  public init(handle: @escaping (ClientError) -> Void) {
+    self.handle = handle
+  }
+
+  public var handle: (ClientError) -> Void
+}
+
+extension ClientErrorCallback {
+  public static let unimplemented = ClientErrorCallback(
+    handle: XCTUnimplemented("\(Self.self)")
+  )
+}
+
+extension ClientErrorCallback {
+  func makeBindingsClientError() -> BindingsClientErrorProtocol {
+    class Reporter: NSObject, BindingsClientErrorProtocol {
+      init(_ callback: ClientErrorCallback) {
+        self.callback = callback
+      }
+
+      let callback: ClientErrorCallback
+
+      func report(_ source: String?, message: String?, trace: String?) {
+        guard let source = source else {
+          fatalError("BindingsClientError.report received `nil` source")
+        }
+        guard let message = message else {
+          fatalError("BindingsClientError.report received `nil` message")
+        }
+        guard let trace = trace else {
+          fatalError("BindingsClientError.report received `nil` trace")
+        }
+        callback.handle(ClientError(
+          source: source,
+          message: message,
+          trace: trace
+        ))
+      }
+    }
+
+    return Reporter(self)
+  }
+}
diff --git a/Sources/ElixxirDAppsSDK/Cmix.swift b/Sources/ElixxirDAppsSDK/Cmix.swift
index 092cff8b..5760d32f 100644
--- a/Sources/ElixxirDAppsSDK/Cmix.swift
+++ b/Sources/ElixxirDAppsSDK/Cmix.swift
@@ -10,6 +10,7 @@ public struct Cmix {
   public var startNetworkFollower: CmixStartNetworkFollower
   public var stopNetworkFollower: CmixStopNetworkFollower
   public var waitForNetwork: CmixWaitForNetwork
+  public var registerClientErrorCallback: CmixRegisterClientErrorCallback
 }
 
 extension Cmix {
@@ -23,7 +24,8 @@ extension Cmix {
       networkFollowerStatus: .live(bindingsCmix),
       startNetworkFollower: .live(bindingsCmix),
       stopNetworkFollower: .live(bindingsCmix),
-      waitForNetwork: .live(bindingsCmix)
+      waitForNetwork: .live(bindingsCmix),
+      registerClientErrorCallback: .live(bindingsCmix)
     )
   }
 }
@@ -38,6 +40,7 @@ extension Cmix {
     networkFollowerStatus: .unimplemented,
     startNetworkFollower: .unimplemented,
     stopNetworkFollower: .unimplemented,
-    waitForNetwork: .unimplemented
+    waitForNetwork: .unimplemented,
+    registerClientErrorCallback: .unimplemented
   )
 }
diff --git a/Sources/ElixxirDAppsSDK/CmixRegisterClientErrorCallback.swift b/Sources/ElixxirDAppsSDK/CmixRegisterClientErrorCallback.swift
new file mode 100644
index 00000000..a8a56a8f
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/CmixRegisterClientErrorCallback.swift
@@ -0,0 +1,28 @@
+import Bindings
+import XCTestDynamicOverlay
+
+public struct CmixRegisterClientErrorCallback {
+  public var run: (ClientErrorCallback) -> Void
+
+  public func callAsFunction(
+    _ callback: ClientErrorCallback
+  ) {
+    run(callback)
+  }
+}
+
+extension CmixRegisterClientErrorCallback {
+  public static func live(_ bindingsCmix: BindingsCmix) -> CmixRegisterClientErrorCallback {
+    CmixRegisterClientErrorCallback { callback in
+      bindingsCmix.registerClientErrorCallback(
+        callback.makeBindingsClientError()
+      )
+    }
+  }
+}
+
+extension CmixRegisterClientErrorCallback {
+  public static let unimplemented = CmixRegisterClientErrorCallback(
+    run: XCTUnimplemented("\(Self.self)")
+  )
+}
diff --git a/Sources/ElixxirDAppsSDK/Legacy/ClientErrorListener.swift b/Sources/ElixxirDAppsSDK/Legacy/ClientErrorListener.swift
deleted file mode 100644
index 7babe34e..00000000
--- a/Sources/ElixxirDAppsSDK/Legacy/ClientErrorListener.swift
+++ /dev/null
@@ -1,48 +0,0 @@
-import Bindings
-
-public struct ClientErrorListener {
-  public var listen: (@escaping (ClientError) -> Void) -> Void
-
-  public func callAsFunction(callback: @escaping (ClientError) -> Void) {
-    listen(callback)
-  }
-}
-
-extension ClientErrorListener {
-  public static func live(bindingsClient: BindingsCmix) -> ClientErrorListener {
-    ClientErrorListener { callback in
-      let listener = Listener(onReport: callback)
-      bindingsClient.registerClientErrorCallback(listener)
-    }
-  }
-}
-
-private final class Listener: NSObject, BindingsClientErrorProtocol {
-  init(onReport: @escaping (ClientError) -> Void) {
-    self.onReport = onReport
-    super.init()
-  }
-
-  let onReport: (ClientError) -> Void
-
-  func report(_ source: String?, message: String?, trace: String?) {
-    guard let source = source else {
-      fatalError("BindingsClientError.source is `nil`")
-    }
-    guard let message = message else {
-      fatalError("BindingsClientError.message is `nil`")
-    }
-    guard let trace = trace else {
-      fatalError("BindingsClientError.trace is `nil`")
-    }
-    onReport(ClientError(source: source, message: message, trace: trace))
-  }
-}
-
-#if DEBUG
-extension ClientErrorListener {
-  public static let failing = ClientErrorListener { _ in
-    fatalError("Not implemented")
-  }
-}
-#endif
-- 
GitLab