OSDN Git Service

不要となっていたプロパティを削除
[kcd/KCD.git] / KCD / Future.swift
1 //
2 //  Future.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2018/01/13.
6 //  Copyright © 2018年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 enum Result<T> {
12     
13     case value(T)
14     
15     case error(Error)
16     
17 //    init(_ value: T) {
18 //
19 //        self = .value(value)
20 //    }
21 //
22 //    init(_ error: Error) {
23 //
24 //        self = .error(error)
25 //    }
26 }
27 extension Result {
28     
29     var value: T? {
30         
31         if case let .value(value) = self { return value }
32         
33         return nil
34     }
35     
36     var error: Error? {
37         
38         if case let .error(error) = self { return error }
39         
40         return nil
41     }
42 }
43
44 enum FutureError: Error {
45     
46     case unsolvedFuture
47     
48     case noSuchElement
49 }
50
51 final class Future<T> {
52     
53     private let semaphore: DispatchSemaphore?
54     
55     private var callbacks: [(Result<T>) -> Void] = []
56     
57     fileprivate var result: Result<T>? {
58         
59         willSet {
60             
61             if result != nil {
62                 
63                 fatalError("Result already seted.")
64             }
65         }
66         
67         didSet {
68             
69             guard let result = self.result else {
70                 
71                 fatalError("set nil to result.")
72             }
73             
74             callbacks.forEach { f in f(result) }
75             callbacks = []
76             
77             semaphore?.signal()
78         }
79     }
80     
81     var isCompleted: Bool {
82         
83         return result != nil
84     }
85     
86     var value: Result<T>? {
87         
88         return result
89     }
90     
91     /// Life cycle
92     init() {
93         
94         // for await()
95         semaphore = DispatchSemaphore(value: 0)
96     }
97     
98     init(in queue: DispatchQueue = .global(), _ block: @escaping () throws -> T) {
99         
100         // for await()
101         semaphore = DispatchSemaphore(value: 0)
102         
103         queue.async {
104             
105             defer { self.semaphore?.signal() }
106             
107             do {
108                 
109                 self.result = .value(try block())
110                 
111             } catch {
112                 
113                 self.result = .error(error)
114             }
115         }
116     }
117     
118     init(_ result: Result<T>) {
119         
120         semaphore = nil
121         
122         self.result = result
123     }
124     
125     convenience init(_ value: T) {
126         
127         self.init(.value(value))
128     }
129     
130     convenience init(_ error: Error) {
131         
132         self.init(.error(error))
133     }
134     
135     deinit {
136         
137         semaphore?.signal()
138     }
139 }
140
141 extension Future {
142     
143     ///
144     @discardableResult
145     func await() -> Self {
146         
147         if result == nil {
148             
149             semaphore?.wait()
150             semaphore?.signal()
151         }
152         
153         return self
154     }
155     
156     @discardableResult
157     func onComplete(_ callback: @escaping (Result<T>) -> Void) -> Self {
158         
159         if let r = result {
160             
161             callback(r)
162             
163         } else {
164             
165             callbacks.append(callback)
166         }
167         
168         return self
169     }
170     
171     @discardableResult
172     func onSuccess(_ callback: @escaping (T) -> Void) -> Self {
173         
174         onComplete { result in
175             
176             if case let .value(v) = result {
177                 
178                 callback(v)
179             }
180         }
181         
182         return self
183     }
184     
185     @discardableResult
186     func onFailure(_ callback: @escaping (Error) -> Void) -> Self {
187         
188         onComplete { result in
189             
190             if case let .error(e) = result {
191                 
192                 callback(e)
193             }
194         }
195         
196         return self
197     }
198 }
199
200 extension Future {
201     
202     ///
203     func transform<U>(_ s: @escaping (T) -> U, _ f: @escaping (Error) -> Error) -> Future<U> {
204         
205         return transform { result in
206             
207             switch result {
208                 
209             case let .value(value): return .value(s(value))
210                 
211             case let .error(error): return .error(f(error))
212                 
213             }
214         }
215     }
216     
217     func transform<U>(_ s: @escaping (Result<T>) -> Result<U>) ->Future<U> {
218         
219         return Promise()
220             .complete {
221                 
222                 self.await().value.map(s) ?? .error(FutureError.unsolvedFuture)
223             }
224             .future
225     }
226     
227     func map<U>(_ t: @escaping (T) -> U) -> Future<U> {
228         
229         return transform(t, { $0 })
230     }
231     
232     func flatMap<U>(_ t: @escaping (T) -> Future<U>) -> Future<U> {
233         
234         return Promise()
235             .completeWith {
236                 
237                 switch self.await().value {
238                     
239                 case .value(let v)?: return t(v)
240                     
241                 case .error(let e)?: return Future<U>(e)
242                     
243                 case .none: fatalError("Future not complete")
244                     
245                 }
246             }
247             .future
248     }
249     
250     func filter(_ f: @escaping (T) -> Bool) -> Future<T> {
251         
252         return Promise()
253             .complete {
254                 
255                 if case let .value(v)? = self.await().value, f(v) {
256                     
257                     return .value(v)
258                 }
259                 
260                 return .error(FutureError.noSuchElement)
261             }
262             .future
263     }
264     
265     func recover(_ s: @escaping (Error) throws -> T) -> Future<T> {
266         
267         return transform { result in
268             
269             do {
270                 
271                 return try result.error.map { error in .value(try s(error)) } ?? .error(FutureError.unsolvedFuture)
272                 
273             } catch {
274                 
275                 return .error(error)
276             }
277         }
278     }
279     
280     @discardableResult
281     func andThen(_ f: @escaping (Result<T>) -> Void) -> Future<T> {
282         
283         return Promise<T>()
284             .complete {
285                 
286                 guard let result = self.await().result else {
287                     
288                     fatalError("Future not complete")
289                 }
290                 
291                 f(result)
292                 
293                 return result
294             }
295             .future
296     }
297 }
298
299 private extension Future {
300     
301     func complete(_ result: Result<T>) {
302         
303         self.result = result
304     }
305 }
306
307 private let promiseQueue = DispatchQueue(label: "Promise", attributes: .concurrent)
308 final class Promise<T> {
309     
310     let future: Future<T> = Future<T>()
311     
312     ///
313     func complete(_ result: Result<T>) {
314         
315         future.complete(result)
316     }
317     
318     func success(_ value: T) {
319         
320         complete(.value(value))
321     }
322     
323     func failure(_ error: Error) {
324         
325         complete(.error(error))
326     }
327     
328     func complete(_ completor: @escaping () -> Result<T>) -> Self {
329         
330         promiseQueue.async {
331             
332             self.complete(completor())
333         }
334         
335         return self
336     }
337     
338     func completeWith(_ completor: @escaping () -> Future<T>) -> Self {
339         
340         promiseQueue.async {
341             
342             completor()
343                 .onSuccess {
344                     
345                     self.success($0)
346                     
347                 }
348                 .onFailure {
349                     
350                     self.failure($0)
351                     
352             }
353         }
354         
355         return self
356     }
357 }