Skip to content

Instantly share code, notes, and snippets.

@dmcyk
Created April 18, 2018 11:41
Show Gist options
  • Save dmcyk/a85cc84a60640ccb4db459063c8a8366 to your computer and use it in GitHub Desktop.
Save dmcyk/a85cc84a60640ccb4db459063c8a8366 to your computer and use it in GitHub Desktop.
private typealias Handler<T> = (GenericResult<T>) -> Void
private enum Sealant<T> {
case sealed([Handler<T>])
case resolved(GenericResult<T>)
}
private final class Resolver<T> {
private let lock = NSLock()
private var value: Sealant<T> = .sealed([])
func resolve(_ result: GenericResult<T>) {
lock.lock()
var handlers: [Handler<T>]?
switch value {
case .resolved:
return // already resolved
case .sealed(let _handlers):
handlers = _handlers
value = .resolved(result)
}
lock.unlock()
handlers?.forEach { $0(result) }
}
func inspect(_ call: @escaping (GenericResult<T>) -> Void) {
let result: GenericResult<T>
lock.lock()
switch value {
case .sealed(var handlers):
handlers.append(call)
value = .sealed(handlers)
return
case .resolved(let _result):
result = _result
}
lock.unlock()
call(result)
}
func fulfill(_ newValue: T) {
resolve(.success(newValue))
}
func reject(_ error: Error) {
resolve(.failure(error))
}
}
public struct NetworkFuture<T> {
private let resolver = Resolver<T>()
public func onResolved(_ call: @escaping (GenericResult<T>) -> Void) {
resolver.inspect(call)
}
func fulfill(_ newValue: T) {
resolver.fulfill(newValue)
}
func reject(_ error: Error) {
resolver.reject(error)
}
func resolve(_ result: GenericResult<T>) {
resolver.resolve(result)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment