Last active
April 7, 2020 11:33
-
-
Save myobie/4813b9482ce4057910441ed996c15c0d to your computer and use it in GitHub Desktop.
Make any class a super simple publisher with publish() and complete() functions
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
class Names: SimplePublisher { | |
typealias Output = Result<String, Error> | |
var subscriptions = [SimpleSubscription<Output, Failure>]() | |
let names = ["Alice", "Bob", "Claris", "Doug"] | |
shoutName() { | |
if let name = names.randomElement() { | |
publish(.success(name)) | |
} else { | |
assertionFailure("There are def some names in there...") | |
} | |
} | |
} | |
let names = Names() | |
let _ = names.sink { result in | |
print("Sinked a name \(name)") | |
} | |
names.shoutName() | |
names.shoutName() | |
names.shoutName() | |
names.shoutName() | |
names.complete() |
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 | |
import Synchronized | |
protocol SimplePublisher: Publisher, Synchronized { | |
var subscriptions: [SimpleSubscription<Output, Failure>] { get set } | |
} | |
extension SimplePublisher { | |
public func receive<S>(subscriber: S) where S : Subscriber, Failure == S.Failure, Output == S.Input { | |
let subscription = SimpleSubscription(subscriber: AnySubscriber(subscriber)) | |
subscriber.receive(subscription: subscription) | |
sync { | |
subscriptions.append(subscription) | |
} | |
} | |
func publish(_ output: Output) { | |
var subscriptions = [SimpleSubscription<Output, Failure>]() | |
sync { | |
subscriptions = self.subscriptions | |
} | |
for subscription in subscriptions { | |
guard let demand = subscription.demand else { continue } | |
guard demand > 0 else { continue } | |
let newDemand = subscription.subscriber.receive(output) | |
subscription.request(newDemand) | |
} | |
} | |
func complete() { | |
complete(.finished) | |
} | |
func complete(_ failure: Failure) { | |
complete(.failure(failure)) | |
} | |
func complete(_ failure: Subscribers.Completion<Failure>) { | |
var subscriptions = [SimpleSubscription<Output, Failure>]() | |
sync { | |
subscriptions = self.subscriptions | |
self.subscriptions.removeAll() | |
} | |
for subscription in subscriptions { | |
subscription.subscriber.receive(completion: failure) | |
} | |
} | |
} |
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 | |
class SimpleSubscription<Input, Failure: Error>: Subscription { | |
let subscriber: AnySubscriber<Input, Failure> | |
var demand: Subscribers.Demand? = nil | |
init(subscriber: AnySubscriber<Input, Failure>) { | |
self.subscriber = subscriber | |
} | |
func request(_ demand: Subscribers.Demand) { | |
self.demand = demand | |
} | |
func cancel() { | |
self.demand = nil | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment