|
1 | 1 | //
|
2 |
| -// Dictionary+FutureType.swift |
| 2 | +// DictionaryFuture.swift |
3 | 3 | // GraphQL
|
4 | 4 | //
|
5 |
| -// Created by Kim de Vos on 26/05/2018. |
| 5 | +// Created by Jeff Seibert on 3/9/18. |
6 | 6 | //
|
7 | 7 |
|
8 | 8 | import Foundation
|
9 | 9 | import NIO
|
10 |
| - |
11 |
| -/// !! From Vapor Async start |
12 |
| - |
13 |
| -/// Callback for accepting a result. |
14 |
| -public typealias FutureResultCallback<T> = (FutureResult<T>) -> () |
15 |
| - |
16 |
| -/// A future result type. |
17 |
| -/// Concretely implemented by `Future<T>` |
18 |
| -public protocol FutureType { |
19 |
| - /// This future's expectation. |
20 |
| - associatedtype Expectation |
21 |
| - |
22 |
| - /// This future's result type. |
23 |
| - typealias Result = FutureResult<Expectation> |
24 |
| - |
25 |
| - /// Adds a new awaiter to this `Future` that will be called when the result is ready. |
26 |
| - func addAwaiter(callback: @escaping FutureResultCallback<Expectation>) |
27 |
| -} |
28 |
| - |
29 |
| -extension EventLoopFuture: FutureType { |
30 |
| - /// See `FutureType`. |
31 |
| - public typealias Expectation = T |
32 |
| - |
33 |
| - /// See `FutureType`. |
34 |
| - public func addAwaiter(callback: @escaping (FutureResult<T>) -> ()) { |
35 |
| - _ = self.map { result in |
36 |
| - callback(.success(result)) |
37 |
| - }.mapIfError { error in |
38 |
| - callback(.error(error)) |
39 |
| - } |
40 |
| - } |
41 |
| -} |
42 |
| - |
43 |
| -// Indirect so futures can be nested. |
44 |
| -public indirect enum FutureResult<T> { |
45 |
| - case error(Error) |
46 |
| - case success(T) |
47 |
| - |
48 |
| - /// Returns the result error or `nil` if the result contains expectation. |
49 |
| - public var error: Error? { |
50 |
| - switch self { |
51 |
| - case .error(let error): |
52 |
| - return error |
53 |
| - default: |
54 |
| - return nil |
55 |
| - } |
56 |
| - } |
57 |
| - |
58 |
| - /// Returns the result expectation or `nil` if the result contains an error. |
59 |
| - public var result: T? { |
60 |
| - switch self { |
61 |
| - case .success(let expectation): |
62 |
| - return expectation |
63 |
| - default: |
64 |
| - return nil |
65 |
| - } |
66 |
| - } |
67 |
| - |
68 |
| - /// Throws an error if this contains an error, returns the Expectation otherwise |
69 |
| - public func unwrap() throws -> T { |
70 |
| - switch self { |
71 |
| - case .success(let data): |
72 |
| - return data |
73 |
| - case .error(let error): |
74 |
| - throw error |
75 |
| - } |
76 |
| - } |
77 |
| -} |
78 |
| - |
79 |
| -extension Collection where Element : FutureType { |
80 |
| - /// Flattens an array of futures into a future with an array of results. |
81 |
| - /// note: the order of the results will match the order of the |
82 |
| - /// futures in the input array. |
83 |
| - /// |
84 |
| - /// [Learn More →](https://docs.vapor.codes/3.0/async/advanced-futures/#combining-multiple-futures) |
85 |
| - public func flatten(on worker: EventLoopGroup) -> EventLoopFuture<[Element.Expectation]> { |
86 |
| - guard count > 0 else { |
87 |
| - return worker.next().newSucceededFuture(result: []) |
88 |
| - } |
89 |
| - var elements: [Element.Expectation] = [] |
90 |
| - |
91 |
| - let promise: EventLoopPromise<[Element.Expectation]> = worker.next().newPromise() |
92 |
| - elements.reserveCapacity(self.count) |
93 |
| - |
94 |
| - for element in self { |
95 |
| - element.addAwaiter { result in |
96 |
| - switch result { |
97 |
| - case .error(let error): promise.fail(error: error) |
98 |
| - case .success(let expectation): |
99 |
| - elements.append(expectation) |
100 |
| - |
101 |
| - if elements.count == self.count { |
102 |
| - promise.succeed(result: elements) |
103 |
| - } |
104 |
| - } |
105 |
| - } |
106 |
| - } |
107 |
| - |
108 |
| - return promise.futureResult |
109 |
| - } |
110 |
| -} |
111 |
| - |
112 |
| -/// !! From Vapor Async end |
| 10 | +import Async |
113 | 11 |
|
114 | 12 | extension Dictionary where Value: FutureType {
|
115 | 13 | func flatten(on worker: EventLoopGroup) -> EventLoopFuture<[Key: Value.Expectation]> {
|
| 14 | + var elements: [Key: Value.Expectation] = [:] |
| 15 | + |
116 | 16 | guard self.count > 0 else {
|
117 |
| - return worker.next().newSucceededFuture(result: [:]) |
| 17 | + return worker.next().newSucceededFuture(result: elements) |
118 | 18 | }
|
119 | 19 |
|
120 |
| - var elements: [Key: Value.Expectation] = [:] |
121 |
| - |
122 | 20 | let promise: EventLoopPromise<[Key: Value.Expectation]> = worker.next().newPromise()
|
123 | 21 | elements.reserveCapacity(self.count)
|
124 | 22 |
|
|
0 commit comments