forked from ReactiveX/RxSwift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRxCocoa.swift
155 lines (125 loc) · 4.7 KB
/
RxCocoa.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
146
147
148
149
150
151
152
153
154
//
// RxCocoa.swift
// RxCocoa
//
// Created by Krunoslav Zaher on 2/21/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
// Importing RxCocoa also imports RxRelay
@_exported import RxRelay
import RxSwift
#if os(iOS)
import UIKit
#endif
/// RxCocoa errors.
public enum RxCocoaError
: Swift.Error
, CustomDebugStringConvertible {
/// Unknown error has occurred.
case unknown
/// Invalid operation was attempted.
case invalidOperation(object: Any)
/// Items are not yet bound to user interface but have been requested.
case itemsNotYetBound(object: Any)
/// Invalid KVO Path.
case invalidPropertyName(object: Any, propertyName: String)
/// Invalid object on key path.
case invalidObjectOnKeyPath(object: Any, sourceObject: AnyObject, propertyName: String)
/// Error during swizzling.
case errorDuringSwizzling
/// Casting error.
case castingError(object: Any, targetType: Any.Type)
}
// MARK: Debug descriptions
extension RxCocoaError {
/// A textual representation of `self`, suitable for debugging.
public var debugDescription: String {
switch self {
case .unknown:
return "Unknown error occurred."
case let .invalidOperation(object):
return "Invalid operation was attempted on `\(object)`."
case let .itemsNotYetBound(object):
return "Data source is set, but items are not yet bound to user interface for `\(object)`."
case let .invalidPropertyName(object, propertyName):
return "Object `\(object)` doesn't have a property named `\(propertyName)`."
case let .invalidObjectOnKeyPath(object, sourceObject, propertyName):
return "Unobservable object `\(object)` was observed as `\(propertyName)` of `\(sourceObject)`."
case .errorDuringSwizzling:
return "Error during swizzling."
case let .castingError(object, targetType):
return "Error casting `\(object)` to `\(targetType)`"
}
}
}
// MARK: Error binding policies
func bindingError(_ error: Swift.Error) {
let error = "Binding error: \(error)"
#if DEBUG
rxFatalError(error)
#else
print(error)
#endif
}
/// Swift does not implement abstract methods. This method is used as a runtime check to ensure that methods which intended to be abstract (i.e., they should be implemented in subclasses) are not called directly on the superclass.
func rxAbstractMethod(message: String = "Abstract method", file: StaticString = #file, line: UInt = #line) -> Swift.Never {
rxFatalError(message, file: file, line: line)
}
func rxFatalError(_ lastMessage: @autoclosure () -> String, file: StaticString = #file, line: UInt = #line) -> Swift.Never {
// The temptation to comment this line is great, but please don't, it's for your own good. The choice is yours.
fatalError(lastMessage(), file: file, line: line)
}
func rxFatalErrorInDebug(_ lastMessage: @autoclosure () -> String, file: StaticString = #file, line: UInt = #line) {
#if DEBUG
fatalError(lastMessage(), file: file, line: line)
#else
print("\(file):\(line): \(lastMessage())")
#endif
}
// MARK: casts or fatal error
// workaround for Swift compiler bug, cheers compiler team :)
func castOptionalOrFatalError<T>(_ value: Any?) -> T? {
if value == nil {
return nil
}
let v: T = castOrFatalError(value)
return v
}
func castOrThrow<T>(_ resultType: T.Type, _ object: Any) throws -> T {
guard let returnValue = object as? T else {
throw RxCocoaError.castingError(object: object, targetType: resultType)
}
return returnValue
}
func castOptionalOrThrow<T>(_ resultType: T.Type, _ object: AnyObject) throws -> T? {
if NSNull().isEqual(object) {
return nil
}
guard let returnValue = object as? T else {
throw RxCocoaError.castingError(object: object, targetType: resultType)
}
return returnValue
}
func castOrFatalError<T>(_ value: AnyObject!, message: String) -> T {
let maybeResult: T? = value as? T
guard let result = maybeResult else {
rxFatalError(message)
}
return result
}
func castOrFatalError<T>(_ value: Any!) -> T {
let maybeResult: T? = value as? T
guard let result = maybeResult else {
rxFatalError("Failure converting from \(String(describing: value)) to \(T.self)")
}
return result
}
// MARK: Error messages
let dataSourceNotSet = "DataSource not set"
let delegateNotSet = "Delegate not set"
// MARK: Shared with RxSwift
func rxFatalError(_ lastMessage: String) -> Never {
// The temptation to comment this line is great, but please don't, it's for your own good. The choice is yours.
fatalError(lastMessage)
}