@@ -101,6 +101,18 @@ public struct AnyError: Swift.Error, CustomStringConvertible {
101
101
}
102
102
}
103
103
104
+ /// Represents a string error.
105
+ public struct StringError : Equatable , Codable , CustomStringConvertible , Error {
106
+
107
+ /// The description of the error.
108
+ public let description : String
109
+
110
+ /// Create an instance of StringError.
111
+ public init ( _ description: String ) {
112
+ self . description = description
113
+ }
114
+ }
115
+
104
116
// AnyError specific helpers.
105
117
extension Result where ErrorType == AnyError {
106
118
/// Initialise with something that throws AnyError.
@@ -133,3 +145,55 @@ extension Result where ErrorType == AnyError {
133
145
}
134
146
}
135
147
}
148
+
149
+ extension Result where ErrorType == StringError {
150
+ /// Create an instance of Result<Value, StringError>.
151
+ ///
152
+ /// Errors will be encoded as StringError using their description.
153
+ public init ( string body: ( ) throws -> Value ) {
154
+ do {
155
+ self = . success( try body ( ) )
156
+ } catch let error as StringError {
157
+ self = . failure( error)
158
+ } catch {
159
+ self = . failure( StringError ( String ( describing: error) ) )
160
+ }
161
+ }
162
+ }
163
+
164
+ extension Result : Equatable where Value: Equatable , ErrorType: Equatable { }
165
+
166
+ extension Result : Codable where Value: Codable , ErrorType: Codable {
167
+ private enum CodingKeys : String , CodingKey {
168
+ case success, failure
169
+ }
170
+
171
+ public func encode( to encoder: Encoder ) throws {
172
+ var container = encoder. container ( keyedBy: CodingKeys . self)
173
+ switch self {
174
+ case . success( let value) :
175
+ var unkeyedContainer = container. nestedUnkeyedContainer ( forKey: . success)
176
+ try unkeyedContainer. encode ( value)
177
+ case . failure( let error) :
178
+ var unkeyedContainer = container. nestedUnkeyedContainer ( forKey: . failure)
179
+ try unkeyedContainer. encode ( error)
180
+ }
181
+ }
182
+
183
+ public init ( from decoder: Decoder ) throws {
184
+ let values = try decoder. container ( keyedBy: CodingKeys . self)
185
+ guard let key = values. allKeys. first ( where: values. contains) else {
186
+ throw DecodingError . dataCorrupted ( . init( codingPath: decoder. codingPath, debugDescription: " Did not find a matching key " ) )
187
+ }
188
+ switch key {
189
+ case . success:
190
+ var unkeyedValues = try values. nestedUnkeyedContainer ( forKey: key)
191
+ let value = try unkeyedValues. decode ( Value . self)
192
+ self = . success( value)
193
+ case . failure:
194
+ var unkeyedValues = try values. nestedUnkeyedContainer ( forKey: key)
195
+ let error = try unkeyedValues. decode ( ErrorType . self)
196
+ self = . failure( error)
197
+ }
198
+ }
199
+ }
0 commit comments