OSDN Git Service

ApplicationDirecroriesの中のアプリケーションに依存する部分を分離した
[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: 1)
96         semaphore?.wait()
97     }
98     
99     init(in queue: DispatchQueue = .global(), _ block: @escaping () throws -> T) {
100         
101         semaphore = DispatchSemaphore(value: 1)
102         semaphore?.wait()
103         
104         queue.async {
105             
106             defer { self.semaphore?.signal() }
107             
108             do {
109                 
110                 self.result = Result(try block())
111                 
112             } catch {
113                 
114                 self.result = Result(error)
115             }
116         }
117     }
118     
119     init(_ result: Result<T>) {
120         
121         semaphore = nil
122         
123         self.result = result
124     }
125     
126     convenience init(_ value: T) {
127         
128         self.init(Result(value))
129     }
130     
131     convenience init(_ error: Error) {
132         
133         self.init(Result(error))
134     }
135     
136     deinit {
137         
138         semaphore?.signal()
139     }
140 }
141
142 extension Future {
143     
144     ///
145     @discardableResult
146     func await() -> Self {
147         
148         if result == nil {
149             
150             semaphore?.wait()
151             semaphore?.signal()
152         }
153         
154         return self
155     }
156     
157     @discardableResult
158     func onComplete(_ callback: @escaping (Result<T>) -> Void) -> Self {
159         
160         if let r = result {
161             
162             callback(r)
163             
164         } else {
165             
166             callbacks.append(callback)
167         }
168         
169         return self
170     }
171     
172     @discardableResult
173     func onSuccess(_ callback: @escaping (T) -> Void) -> Self {
174         
175         onComplete { result in
176             
177             if case let .value(v) = result {
178                 
179                 callback(v)
180             }
181         }
182         
183         return self
184     }
185     
186     @discardableResult
187     func onFailure(_ callback: @escaping (Error) -> Void) -> Self {
188         
189         onComplete { result in
190             
191             if case let .error(e) = result {
192                 
193                 callback(e)
194             }
195         }
196         
197         return self
198     }
199 }
200
201 extension Future {
202     
203     ///
204     func transform<U>(_ s: @escaping (T) -> U, _ f: @escaping (Error) -> Error) -> Future<U> {
205         
206         return transform { result in
207             
208             switch result {
209                 
210             case let .value(value): return Result(s(value))
211                 
212             case let .error(error): return Result(f(error))
213                 
214             }
215         }
216     }
217     
218     func transform<U>(_ s: @escaping (Result<T>) -> Result<U>) ->Future<U> {
219         
220         return Promise()
221             .complete {
222                 
223                 self.await().value.map(s) ?? Result(FutureError.unsolvedFuture)
224             }
225             .future
226     }
227     
228     func map<U>(_ t: @escaping (T) -> U) -> Future<U> {
229         
230         return transform(t, { $0 })
231     }
232     
233     func flatMap<U>(_ t: @escaping (T) -> Future<U>) -> Future<U> {
234         
235         return Promise()
236             .completeWith {
237                 
238                 switch self.await().value {
239                     
240                 case .value(let v)?: return t(v)
241                     
242                 case .error(let e)?: return Future<U>(e)
243                     
244                 case .none: fatalError("Future not complete")
245                     
246                 }
247             }
248             .future
249     }
250     
251     func filter(_ f: @escaping (T) -> Bool) -> Future<T> {
252         
253         return Promise()
254             .complete {
255                 
256                 if case let .value(v)? = self.await().value, f(v) {
257                     
258                     return Result(v)
259                 }
260                 
261                 return Result(FutureError.noSuchElement)
262             }
263             .future
264     }
265     
266     func recover(_ s: @escaping (Error) throws -> T) -> Future<T> {
267         
268         return transform { result in
269             
270             do {
271                 
272                 return try result.error.map { error in Result(try s(error)) } ?? Result(FutureError.unsolvedFuture)
273                 
274             } catch {
275                 
276                 return Result(error)
277             }
278         }
279     }
280     
281     @discardableResult
282     func andThen(_ f: @escaping (Result<T>) -> Void) -> Future<T> {
283         
284         return Promise<T>()
285             .complete {
286                 
287                 guard let result = self.await().result else {
288                     
289                     fatalError("Future not complete")
290                 }
291                 
292                 f(result)
293                 
294                 return result
295             }
296             .future
297     }
298 }
299
300 private extension Future {
301     
302     func complete(_ result: Result<T>) {
303         
304         self.result = result
305     }
306 }
307
308 private let promiseQueue = DispatchQueue(label: "Promise", attributes: .concurrent)
309 final class Promise<T> {
310     
311     let future: Future<T> = Future<T>()
312     
313     ///
314     func complete(_ result: Result<T>) {
315         
316         future.complete(result)
317     }
318     
319     func success(_ value: T) {
320         
321         complete(Result(value))
322     }
323     
324     func failure(_ error: Error) {
325         
326         complete(Result(error))
327     }
328     
329     func complete(_ completor: @escaping () -> Result<T>) -> Self {
330         
331         promiseQueue.async {
332             
333             self.complete(completor())
334         }
335         
336         return self
337     }
338     
339     func completeWith(_ completor: @escaping () -> Future<T>) -> Self {
340         
341         promiseQueue.async {
342             
343             completor()
344                 .onSuccess {
345                     
346                     self.success($0)
347                     
348                 }
349                 .onFailure {
350                     
351                     self.failure($0)
352                     
353             }
354         }
355         
356         return self
357     }
358 }