forked from ReactiveCocoa/ReactiveCocoa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Event.swift
145 lines (117 loc) · 2.97 KB
/
Event.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//
// Event.swift
// ReactiveCocoa
//
// Created by Justin Spahr-Summers on 2015-01-16.
// Copyright (c) 2015 GitHub. All rights reserved.
//
/// Represents a signal event.
///
/// Signals must conform to the grammar:
/// `Next* (Failed | Completed | Interrupted)?`
public enum Event<Value, Error: ErrorType> {
/// A value provided by the signal.
case Next(Value)
/// The signal terminated because of an error. No further events will be
/// received.
case Failed(Error)
/// The signal successfully terminated. No further events will be received.
case Completed
/// Event production on the signal has been interrupted. No further events
/// will be received.
case Interrupted
/// Whether this event indicates signal termination (i.e., that no further
/// events will be received).
public var isTerminating: Bool {
switch self {
case .Next:
return false
case .Failed, .Completed, .Interrupted:
return true
}
}
/// Lifts the given function over the event's value.
public func map<U>(f: Value -> U) -> Event<U, Error> {
switch self {
case let .Next(value):
return .Next(f(value))
case let .Failed(error):
return .Failed(error)
case .Completed:
return .Completed
case .Interrupted:
return .Interrupted
}
}
/// Lifts the given function over the event's error.
public func mapError<F>(f: Error -> F) -> Event<Value, F> {
switch self {
case let .Next(value):
return .Next(value)
case let .Failed(error):
return .Failed(f(error))
case .Completed:
return .Completed
case .Interrupted:
return .Interrupted
}
}
/// Unwraps the contained `Next` value.
public var value: Value? {
if case let .Next(value) = self {
return value
} else {
return nil
}
}
/// Unwraps the contained `Error` value.
public var error: Error? {
if case let .Failed(error) = self {
return error
} else {
return nil
}
}
}
public func == <Value: Equatable, Error: Equatable> (lhs: Event<Value, Error>, rhs: Event<Value, Error>) -> Bool {
switch (lhs, rhs) {
case let (.Next(left), .Next(right)):
return left == right
case let (.Failed(left), .Failed(right)):
return left == right
case (.Completed, .Completed):
return true
case (.Interrupted, .Interrupted):
return true
default:
return false
}
}
extension Event: CustomStringConvertible {
public var description: String {
switch self {
case let .Next(value):
return "NEXT \(value)"
case let .Failed(error):
return "FAILED \(error)"
case .Completed:
return "COMPLETED"
case .Interrupted:
return "INTERRUPTED"
}
}
}
/// Event protocol for constraining signal extensions
public protocol EventType {
// The value type of an event.
associatedtype Value
/// The error type of an event. If errors aren't possible then `NoError` can be used.
associatedtype Error: ErrorType
/// Extracts the event from the receiver.
var event: Event<Value, Error> { get }
}
extension Event: EventType {
public var event: Event<Value, Error> {
return self
}
}