Skip to content

Instantly share code, notes, and snippets.

@chadaustin
Created October 20, 2016 19:20
Show Gist options
  • Save chadaustin/0677b7cef8b0f0a12f583f70ea987be8 to your computer and use it in GitHub Desktop.
Save chadaustin/0677b7cef8b0f0a12f583f70ea987be8 to your computer and use it in GitHub Desktop.
data AnyObservable t = forall o. (ObservableData o, DataType o ~ t) => AnyObservable o
/// Existential type wrapper around an ObservableData constraining the data type to the type parameter T.
/// Useful as a return value for functions that return some observable but the concrete observable type isn't known.
public final class AnyObservableData<T>: ObservableData {
// MARK: Init
public static func make<U: ObservableData>(_ observable: U) -> AnyObservableData<U.Event> {
return AnyObservableData<U.Event>(
getter: { return observable.data },
addObserver: { cb in return observable.addObserver(cb) },
removeObserver: { token in return observable.removeObserver(with: token) }
)
}
// ObservableData
public typealias Event = T
public var data: T {
return getter()
}
public func addObserver(_ observer: @escaping (T) -> Void) -> ObserverToken {
return self.addObserver_(observer)
}
public func removeObserver(with token: ObserverToken) {
return self.removeObserver_(token)
}
// MARK: Private
private init(
getter: @escaping () -> T,
addObserver: @escaping (@escaping (T) -> Void) -> ObserverToken,
removeObserver: @escaping (ObserverToken) -> Void
) {
self.getter = getter
self.addObserver_ = addObserver
self.removeObserver_ = removeObserver
}
private let getter: () -> T
private let addObserver_: (@escaping (T) -> Void) -> ObserverToken
private let removeObserver_: (ObserverToken) -> Void
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment