OSDN Git Service

andThenを追加
[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         self = .value(value)
19     }
20     init(_ error: Error) {
21         self = .error(error)
22     }
23 }
24 extension Result {
25     
26     var value: T? {
27         if case let .value(value) = self { return value }
28         return nil
29     }
30     var error: Error? {
31         if case let .error(error) = self { return error }
32         return nil
33     }
34 }
35
36 enum FutureError: Error {
37     
38     case unsolvedFuture
39     
40     case noSuchElement
41 }
42
43 private let defaultWaitingQueue = DispatchQueue(label: "Future", attributes: .concurrent)
44 private final class FutureSynchronous {
45     
46     private let queue: DispatchQueue
47     private let semaphore = DispatchSemaphore(value: 1)
48     
49     init(queue: DispatchQueue? = nil) {
50         
51         self.queue = queue ?? defaultWaitingQueue
52     }
53     
54     func excuteAfterWaiting(_ block: @escaping () -> Void) {
55         
56         queue.async {
57             self.semaphore.wait()
58             block()
59             self.semaphore.signal()
60         }
61     }
62     
63     func startWaiting() {
64         
65         self.semaphore.wait()
66     }
67     
68     func stopWaiting() {
69         
70         self.semaphore.signal()
71     }
72 }
73
74 class Future<T> {
75     
76     private let synchronous: FutureSynchronous
77     
78     fileprivate var result: Result<T>? {
79         willSet {
80             if result != nil {
81                 fatalError("Result already seted.")
82             }
83         }
84         didSet {
85             if result == nil {
86                 fatalError("set nil to result.")
87             }
88             synchronous.stopWaiting()
89         }
90     }
91     
92     var isCompleted: Bool {
93         return result != nil
94     }
95     var value: Result<T>? {
96         return result
97     }
98     
99     /// Life cycle
100     init() {
101         
102         self.synchronous = FutureSynchronous()
103         
104         synchronous.startWaiting()
105     }
106     
107     init(_ block: @escaping () throws -> T) {
108         
109         self.synchronous = FutureSynchronous()
110         
111         synchronous.excuteAfterWaiting {
112             do {
113                 self.result = Result(try block())
114             } catch {
115                 self.result = Result(error)
116             }
117         }
118     }
119     
120     init(_ result: Result<T>) {
121         
122         self.synchronous = FutureSynchronous()
123         
124         self.result = result
125     }
126     convenience init(_ value: T) {
127         
128         self.init(Result(value))
129     }
130     convenience init(_ error: Error) {
131         
132         self.init(Result(error))
133     }
134     
135     deinit {
136         synchronous.stopWaiting()
137     }
138 }
139
140 extension Future {
141     
142     ///
143     @discardableResult
144     func await() -> Self {
145         
146         synchronous.startWaiting()
147         synchronous.stopWaiting()
148         
149         return self
150     }
151     
152     @discardableResult
153     func onComplete(_ block: @escaping (Result<T>) -> Void) -> Self {
154         
155         synchronous.excuteAfterWaiting {
156             self.value.map(block)
157         }
158         
159         return self
160     }
161     
162     @discardableResult
163     func onSuccess(_ block: @escaping (T) -> Void) -> Self {
164         
165         onComplete { result in result.value.map(block) }
166         
167         return self
168     }
169     
170     @discardableResult
171     func onFailure(_ block: @escaping (Error) -> Void) -> Self {
172         
173         onComplete { result in result.error.map(block) }
174         
175         return self
176     }
177 }
178
179 extension Future {
180     
181     ///
182     func transform<U>(_ s: @escaping (T) -> U, _ f: @escaping (Error) -> Error) -> Future<U> {
183         
184         return transform { result in
185             switch result {
186             case let .value(value): return Result(s(value))
187             case let .error(error): return Result(f(error))
188             }
189         }
190     }
191     
192     func transform<U>(_ s: @escaping (Result<T>) -> Result<U>) ->Future<U> {
193         
194         return Promise()
195             .complete {
196                 self.await().value.map(s) ?? Result(FutureError.unsolvedFuture)
197             }
198             .future
199     }
200     
201     func map<U>(_ t: @escaping (T) -> U) -> Future<U> {
202         
203         return transform(t, { $0 })
204     }
205     
206     func flatMap<U>(_ t: @escaping (T) -> Future<U>) -> Future<U> {
207         
208         return Promise()
209             .completeWith {
210                 switch self.await().value {
211                 case .value(let v)?: return t(v)
212                 case .error(let e)?: return Future<U>(e)
213                 case .none: fatalError("Future not complete")
214                 }
215             }
216             .future
217     }
218     
219     func filter(_ f: @escaping (T) -> Bool) -> Future<T> {
220         
221         return Promise()
222             .complete {
223                 if case let .value(v)? = self.await().value, f(v) {
224                     return Result(v)
225                 }
226                 return Result(FutureError.noSuchElement)
227             }
228             .future
229     }
230     
231     func recover(_ s: @escaping (Error) throws -> T) -> Future<T> {
232         
233         return transform { result in
234             do {
235                 return try result.error.map { error in Result(try s(error)) } ?? Result(FutureError.unsolvedFuture)
236             } catch {
237                 return Result(error)
238             }
239         }
240     }
241     
242     @discardableResult
243     func andThen(_ f: @escaping (Result<T>) -> Void) -> Future<T> {
244         
245         return Promise<T>()
246             .complete {
247                 guard let result = self.await().result else { fatalError("Future not complete") }
248                 
249                 f(result)
250                 return result
251             }
252             .future
253     }
254 }
255
256 private extension Future {
257     
258     func complete(_ result: Result<T>) {
259         
260         self.result = result
261     }
262 }
263
264 private let promiseQueue = DispatchQueue(label: "Promise", attributes: .concurrent)
265 final class Promise<T> {
266     
267     let future: Future<T> = Future<T>()
268     
269     ///
270     func complete(_ result: Result<T>) {
271         
272         future.complete(result)
273     }
274     func success(_ value: T) {
275         
276         complete(Result(value))
277     }
278     func failure(_ error: Error) {
279         
280         complete(Result(error))
281     }
282     
283     func complete(_ completor: @escaping () -> Result<T>) -> Self {
284         
285         promiseQueue.async {
286             self.complete(completor())
287         }
288         
289         return self
290     }
291     
292     func completeWith(_ completor: @escaping () -> Future<T>) -> Self {
293         
294         promiseQueue.async {
295             completor()
296                 .onSuccess {
297                     self.success($0)
298                 }
299                 .onFailure {
300                     self.failure($0)
301             }
302         }
303         
304         return self
305     }
306 }