-
Notifications
You must be signed in to change notification settings - Fork 0
/
FutureMap.swift
125 lines (99 loc) · 4.91 KB
/
FutureMap.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import Combine
extension Future {
// `P` must be a publisher which receives just one value.
private convenience init<P: Publisher>(_ publisher: P) where P.Output == Output, P.Failure == Failure {
self.init { promise in
var count = 0
let keep: Keep<AnyCancellable> = .init()
keep.value = publisher
.handleEvents(receiveCancel: { keep.value = nil })
.sink(receiveCompletion: { completion in
assert(count == 1)
if case .failure(let error) = completion {
promise(.failure(error))
}
keep.value = nil
}, receiveValue: { value in
assert(count == 0)
count += 1
promise(.success(value))
})
}
}
public func futureAllSatisfy(_ predicate: @escaping (Output) -> Bool) -> Future<Bool, Failure> {
Future<Bool, Failure>(allSatisfy(predicate))
}
public func futureCatch<E: Error>(_ handler: @escaping (Failure) -> Future<Output, E>) -> Future<Output, E> {
Future<Output, E>(`catch`(handler))
}
public func futureContains(where predicate: @escaping (Output) -> Bool) -> Future<Bool, Failure> {
Future<Bool, Failure>(contains(where: predicate))
}
public func futureFlatMap<T>(maxPublishers: Subscribers.Demand = .unlimited, _ transform: @escaping (Output) -> Future<T, Failure>) -> Future<T, Failure> {
Future<T, Failure>(flatMap(maxPublishers: maxPublishers, transform))
}
public func futureMap<T>(_ transform: @escaping (Output) -> T) -> Future<T, Failure> {
Future<T, Failure>(map(transform))
}
public func futureMapError<E: Error>(_ transform: @escaping (Failure) -> E) -> Future<Output, E> {
Future<Output, E>(mapError(transform))
}
public func futureMax(by areInIncreasingOrder: @escaping (Output, Output) -> Bool) -> Future<Output, Failure> {
Future<Output, Failure>(max(by: areInIncreasingOrder))
}
public func futureMin(by areInIncreasingOrder: @escaping (Output, Output) -> Bool) -> Future<Output, Failure> {
Future<Output, Failure>(min(by: areInIncreasingOrder))
}
public func futurePrint(_ prefix: String = "", to stream: TextOutputStream? = nil) -> Future<Output, Failure> {
Future<Output, Failure>(print(prefix, to: stream))
}
public func futureReceive<S: Scheduler>(on scheduler: S, options: S.SchedulerOptions? = nil) -> Future<Output, Failure> {
Future<Output, Failure>(receive(on: scheduler, options: options))
}
public func futureReduce<T>(_ initialResult: T, _ nextPartialResult: @escaping (T, Output) -> T) -> Future<T, Failure> {
Future<T, Failure>(reduce(initialResult, nextPartialResult))
}
public func futureReplaceError(with output: Output) -> Future<Output, Never> {
Future<Output, Never>(replaceError(with: output))
}
public func futureReplaceNil<T>(with output: T) -> Future<T, Failure> where Output == T? {
Future<T, Failure>(replaceNil(with: output))
}
public func futureTryAllSatisfy(_ predicate: @escaping (Output) throws -> Bool) -> Future<Bool, Error> {
Future<Bool, Error>(tryAllSatisfy(predicate))
}
public func futureTryCatch<E: Error>(_ handler: @escaping (Failure) throws -> Future<Output, E>) -> Future<Output, Error> {
Future<Output, Error>(tryCatch(handler))
}
public func futureTryContains(where predicate: @escaping (Output) throws -> Bool) -> Future<Bool, Error> {
Future<Bool, Error>(tryContains(where: predicate))
}
public func futureTryMap<T>(_ transform: @escaping (Output) throws -> T) -> Future<T, Error> {
Future<T, Error>(tryMap(transform))
}
public func futureTryMax(by areInIncreasingOrder: @escaping (Output, Output) throws -> Bool) -> Future<Output, Error> {
Future<Output, Error>(tryMax(by: areInIncreasingOrder))
}
public func futureTryMin(by areInIncreasingOrder: @escaping (Output, Output) throws -> Bool) -> Future<Output, Error> {
Future<Output, Error>(tryMin(by: areInIncreasingOrder))
}
func futureTryReduce<T>(_ initialResult: T, _ nextPartialResult: @escaping (T, Output) throws -> T) -> Future<T, Error> {
Future<T, Error>(tryReduce(initialResult, nextPartialResult))
}
}
extension Future where Output: Equatable {
public func futureContains(_ output: Output) -> Future<Bool, Failure> {
Future<Bool, Failure>(contains(output))
}
}
extension Future where Output: Comparable {
public func futureMax() -> Future<Output, Failure> {
Future<Output, Failure>(max())
}
public func futureMin() -> Future<Output, Failure> {
Future<Output, Failure>(min())
}
}
private final class Keep<Value: AnyObject> {
var value: Value?
}