From eaaefca733f218b2f04ef392d75ca3905738ba11 Mon Sep 17 00:00:00 2001 From: Yehor Popovych Date: Fri, 17 Nov 2023 12:24:28 +0000 Subject: [PATCH] throwing methods for services --- .../Extension/ActionViewController.swift | 12 +++---- .../Swift/Extension/TestSigningService.swift | 11 ++++--- .../TesseractService/SubstrateService.swift | 10 +++--- Sources/TesseractService/TestService.swift | 6 ++-- .../TesseractShared/SubstrateService.swift | 33 ++++++++++++++++++- Sources/TesseractShared/TestService.swift | 12 ++++++- .../TesseractError+Ext.swift | 28 ++++++++++++++-- 7 files changed, 91 insertions(+), 21 deletions(-) diff --git a/Examples/Swift/Extension/ActionViewController.swift b/Examples/Swift/Extension/ActionViewController.swift index bed23c5..ad3918a 100644 --- a/Examples/Swift/Extension/ActionViewController.swift +++ b/Examples/Swift/Extension/ActionViewController.swift @@ -12,7 +12,7 @@ import TesseractService class ActionViewController: UIViewController, TestSigningServiceDelegate { @IBOutlet weak var textView: UILabel! - var continuation: UnsafeContinuation, Never>? + var continuation: UnsafeContinuation? var tesseract: Tesseract! @@ -28,25 +28,25 @@ class ActionViewController: UIViewController, TestSigningServiceDelegate { } @MainActor - func acceptTx(tx: String) async -> Result { - return await withUnsafeContinuation { cont in + func acceptTx(tx: String) async throws -> Bool { + try await withUnsafeThrowingContinuation { cont in self.continuation = cont self.textView.text = tx } } @IBAction func allow() { - self.continuation?.resume(returning: .success(true)) + self.continuation?.resume(returning: true) self.continuation = nil } @IBAction func reject() { - self.continuation?.resume(returning: .success(false)) + self.continuation?.resume(returning: false) self.continuation = nil } @IBAction func cancel() { - self.continuation?.resume(returning: .failure(.cancelled)) + self.continuation?.resume(throwing: TesseractError.cancelled) self.continuation = nil } } diff --git a/Examples/Swift/Extension/TestSigningService.swift b/Examples/Swift/Extension/TestSigningService.swift index 6dbb45e..3ee316d 100644 --- a/Examples/Swift/Extension/TestSigningService.swift +++ b/Examples/Swift/Extension/TestSigningService.swift @@ -9,7 +9,7 @@ import Foundation import TesseractService protocol TestSigningServiceDelegate: AnyObject { - func acceptTx(tx: String) async -> Result + func acceptTx(tx: String) async throws -> Bool } class TestSigningService: TestService { @@ -21,12 +21,13 @@ class TestSigningService: TestService { self.signature = signature } - func signTransation(req: String) async -> Result { + func signTransation(req: String) async throws -> String { guard let delegate = self.delegate else { - return .failure(.null(reason: "TestSigningService delegate is empty")) + throw TesseractError.null(TestSigningService.self) } - return await delegate.acceptTx(tx: req).flatMap { - $0 ? .success(req + self.signature) : .failure(.cancelled) + guard try await delegate.acceptTx(tx: req) else { + throw TesseractError.cancelled } + return req + signature } } diff --git a/Sources/TesseractService/SubstrateService.swift b/Sources/TesseractService/SubstrateService.swift index 392936c..fa01962 100644 --- a/Sources/TesseractService/SubstrateService.swift +++ b/Sources/TesseractService/SubstrateService.swift @@ -20,10 +20,12 @@ extension CTesseract.SubstrateService: CoreService { } } -public protocol SubstrateService: TesseractShared.SubstrateService, Service +public protocol SubstrateServiceResult: TesseractShared.SubstrateServiceResult, Service where Core == CTesseract.SubstrateService {} -public extension SubstrateService { +public protocol SubstrateService: SubstrateServiceResult, TesseractShared.SubstrateService {} + +public extension SubstrateServiceResult { func toCore() -> Core { var value = Core(value: self) value.get_account = substrate_service_get_account @@ -37,7 +39,7 @@ private func substrate_service_get_account( accountType: CTesseract.SubstrateAccountType ) -> CFuture_SubstrateGetAccountResponse { CFuture_SubstrateGetAccountResponse { - await this.unowned((any SubstrateService).self).castError().asyncFlatMap { + await this.unowned((any SubstrateServiceResult).self).castError().asyncFlatMap { await $0.getAccount( type: TesseractShared.SubstrateAccountType(cvalue: accountType) ) @@ -55,7 +57,7 @@ private func substrate_service_sign( let metadata = metadata.copied() let types = types.copied() return CFutureData { - await this.unowned((any SubstrateService).self).castError().asyncFlatMap { + await this.unowned((any SubstrateServiceResult).self).castError().asyncFlatMap { await $0.signTransation(type: TesseractShared.SubstrateAccountType(cvalue: type), path: path, extrinsic: extrinsic, metadata: metadata, types: types) diff --git a/Sources/TesseractService/TestService.swift b/Sources/TesseractService/TestService.swift index 8be1582..33f3aa0 100644 --- a/Sources/TesseractService/TestService.swift +++ b/Sources/TesseractService/TestService.swift @@ -17,9 +17,11 @@ extension CTesseract.TestService: CoreService { } } -public protocol TestService: TesseractShared.TestService, Service +public protocol TestServiceResult: TesseractShared.TestServiceResult, Service where Core == CTesseract.TestService {} +public protocol TestService: TestServiceResult, TesseractShared.TestService {} + public extension TestService { func toCore() -> Core { var value = Core(value: self) @@ -33,7 +35,7 @@ private func test_service_sign(this: UnsafePointer!, { let req = req.copied() return CFutureString { - await this.unowned((any TestService).self).castError().asyncFlatMap { + await this.unowned((any TestServiceResult).self).castError().asyncFlatMap { await $0.signTransation(req: req) } } diff --git a/Sources/TesseractShared/SubstrateService.swift b/Sources/TesseractShared/SubstrateService.swift index 50d8a45..03d0009 100644 --- a/Sources/TesseractShared/SubstrateService.swift +++ b/Sources/TesseractShared/SubstrateService.swift @@ -27,7 +27,7 @@ public struct SubstrateGetAccountResponse { } } -public protocol SubstrateService { +public protocol SubstrateServiceResult { func getAccount( type: SubstrateAccountType ) async -> Result @@ -38,6 +38,37 @@ public protocol SubstrateService { ) async -> Result } +public protocol SubstrateService: SubstrateServiceResult { + func getAccount( + type: SubstrateAccountType + ) async throws -> SubstrateGetAccountResponse + + func signTransation( + type: SubstrateAccountType, path: String, + extrinsic: Data, metadata: Data, types: Data + ) async throws -> Data +} + +public extension SubstrateService { + func getAccount( + type: SubstrateAccountType + ) async -> Result { + await Result { try await getAccount(type: type) } + } + + func signTransation( + type: SubstrateAccountType, path: String, + extrinsic: Data, metadata: Data, types: Data + ) async -> Result { + await Result { + try await signTransation(type: type, path: path, + extrinsic: extrinsic, + metadata: metadata, + types: types) + } + } +} + extension CTesseract.SubstrateAccountType: CType { public init() { self.init(0) } } diff --git a/Sources/TesseractShared/TestService.swift b/Sources/TesseractShared/TestService.swift index a534d70..36f0503 100644 --- a/Sources/TesseractShared/TestService.swift +++ b/Sources/TesseractShared/TestService.swift @@ -10,6 +10,16 @@ import Foundation import TesseractTransportsShared #endif -public protocol TestService { +public protocol TestServiceResult { func signTransation(req: String) async -> Result } + +public protocol TestService: TestServiceResult { + func signTransation(req: String) async throws -> String +} + +public extension TestService { + func signTransation(req: String) async -> Result { + await Result { try await signTransation(req: req) } + } +} diff --git a/Sources/TesseractTransportsShared/TesseractError+Ext.swift b/Sources/TesseractTransportsShared/TesseractError+Ext.swift index 0392f71..0c08793 100644 --- a/Sources/TesseractTransportsShared/TesseractError+Ext.swift +++ b/Sources/TesseractTransportsShared/TesseractError+Ext.swift @@ -26,6 +26,18 @@ public extension Result where Failure: TesseractErrorConvertible { } public extension Result where Failure == TesseractError { + init(tesseract fn: () async throws -> Success) async { + do { + self = await .success(try fn()) + } catch let err as TesseractErrorConvertible { + self = .failure(err.tesseract) + } catch let err as CErrorConvertible { + self = .failure(TesseractError(cError: err.cError)) + } catch { + self = .failure(TesseractError(parsing: error as NSError)) + } + } + func castError() -> Result { mapError { E(tesseract: $0) } } @@ -36,8 +48,20 @@ public extension Result where Failure == TesseractError { } public extension TesseractError { - init(parsing error: NSError) { - self.init(cError: InteropError(parsing: error)) + @inlinable init(parsing error: NSError) { + self.init(cError: .init(parsing: error)) + } + + @inlinable static func null(_ type: T.Type) -> Self { + .init(cError: .null(type)) + } + + @inlinable static func panic(reason: String) -> Self { + .init(cError: .panic(reason: reason)) + } + + @inlinable static func cast(from: F.Type, to: T.Type) -> Self { + .init(cError: .cast(from: from, to: to)) } }