Skip to content

Instantly share code, notes, and snippets.

@swhitty
Created June 26, 2021 01:07
Show Gist options
  • Save swhitty/d2023926fc3ee20e8112f4c051a22511 to your computer and use it in GitHub Desktop.
Save swhitty/d2023926fc3ee20e8112f4c051a22511 to your computer and use it in GitHub Desktop.
import Combine
extension Publisher {
/// Binds a publisher to a subscriber with a resulting cancellable
func bind<S: Subscriber>(to subscriber: S) -> AnyCancellable where S.Failure == Failure, S.Input == Output {
let binding = Binding(subscriber)
subscribe(binding)
return AnyCancellable(binding.cancel)
}
}
/// `Binding` is a simple wrapper for a Combine subscriber that can be cancelled.
private final class Binding<Input, Failure>: Subscriber where Failure: Error {
private var upstream: AnySubscriber<Input, Failure>?
private var subscription: Subscription?
init<S: Subscriber>(_ subscriber: S) where S.Input == Input, S.Failure == Failure {
upstream = AnySubscriber(subscriber)
}
func receive(subscription: Subscription) {
self.subscription = subscription
upstream!.receive(subscription: subscription)
}
func receive(_ input: Input) -> Subscribers.Demand {
upstream!.receive(input)
}
func receive(completion: Subscribers.Completion<Failure>) {
upstream!.receive(completion: completion)
}
func cancel() {
subscription?.cancel()
subscription = nil
upstream = nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment