|
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