Created
November 1, 2023 22:47
-
-
Save aduuub/468c2b7338ffe43da47e6662f3022db6 to your computer and use it in GitHub Desktop.
A Publisher that turns a completion with Result into a Combine Publisher
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import Combine | |
public struct ResultPublisher<Success, Failure>: Publisher where Failure: Error { | |
public typealias Output = Success | |
public typealias Failure = Failure | |
public typealias ResultCallback = (Result<Success, Failure>) -> Void | |
let invocation: (@escaping ResultCallback) -> Void | |
public init(_ invocation: @escaping (@escaping ResultCallback) -> Void) { | |
self.invocation = invocation | |
} | |
public func receive<S>(subscriber: S) where S: Subscriber, Failure == S.Failure, Success == S.Input { | |
let subscription = ResultSubscription( | |
invocation: invocation, | |
subscriber: subscriber | |
) | |
subscriber.receive(subscription: subscription) | |
} | |
} | |
private extension ResultPublisher { | |
class ResultSubscription<S: Subscriber>: Subscription where S.Input == Success, S.Failure == Failure { | |
private let invocation: (@escaping ResultCallback) -> Void | |
private var subscriber: S? | |
init(invocation: @escaping (@escaping ResultCallback) -> Void, subscriber: S) { | |
self.invocation = invocation | |
self.subscriber = subscriber | |
invokeCallback() | |
} | |
func request(_ demand: Subscribers.Demand) { | |
// Adjust the demand in case you need to | |
} | |
func cancel() { | |
subscriber = nil | |
} | |
private func invokeCallback() { | |
guard let subscriber = subscriber else { | |
return | |
} | |
invocation { result in | |
switch result { | |
case .success(let value): | |
_ = subscriber.receive(value) | |
case .failure(let error): | |
subscriber.receive(completion: .failure(error)) | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment