added iOS source code
[wl-app.git] / iOS / Pods / Alamofire / Source / Result.swift
1 //
2 //  Result.swift
3 //
4 //  Copyright (c) 2014-2017 Alamofire Software Foundation (http://alamofire.org/)
5 //
6 //  Permission is hereby granted, free of charge, to any person obtaining a copy
7 //  of this software and associated documentation files (the "Software"), to deal
8 //  in the Software without restriction, including without limitation the rights
9 //  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 //  copies of the Software, and to permit persons to whom the Software is
11 //  furnished to do so, subject to the following conditions:
12 //
13 //  The above copyright notice and this permission notice shall be included in
14 //  all copies or substantial portions of the Software.
15 //
16 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 //  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 //  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 //  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 //  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 //  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 //  THE SOFTWARE.
23 //
24
25 import Foundation
26
27 /// Used to represent whether a request was successful or encountered an error.
28 ///
29 /// - success: The request and all post processing operations were successful resulting in the serialization of the
30 ///            provided associated value.
31 ///
32 /// - failure: The request encountered an error resulting in a failure. The associated values are the original data
33 ///            provided by the server as well as the error that caused the failure.
34 public enum Result<Value> {
35     case success(Value)
36     case failure(Error)
37
38     /// Returns `true` if the result is a success, `false` otherwise.
39     public var isSuccess: Bool {
40         switch self {
41         case .success:
42             return true
43         case .failure:
44             return false
45         }
46     }
47
48     /// Returns `true` if the result is a failure, `false` otherwise.
49     public var isFailure: Bool {
50         return !isSuccess
51     }
52
53     /// Returns the associated value if the result is a success, `nil` otherwise.
54     public var value: Value? {
55         switch self {
56         case .success(let value):
57             return value
58         case .failure:
59             return nil
60         }
61     }
62
63     /// Returns the associated error value if the result is a failure, `nil` otherwise.
64     public var error: Error? {
65         switch self {
66         case .success:
67             return nil
68         case .failure(let error):
69             return error
70         }
71     }
72 }
73
74 // MARK: - CustomStringConvertible
75
76 extension Result: CustomStringConvertible {
77     /// The textual representation used when written to an output stream, which includes whether the result was a
78     /// success or failure.
79     public var description: String {
80         switch self {
81         case .success:
82             return "SUCCESS"
83         case .failure:
84             return "FAILURE"
85         }
86     }
87 }
88
89 // MARK: - CustomDebugStringConvertible
90
91 extension Result: CustomDebugStringConvertible {
92     /// The debug textual representation used when written to an output stream, which includes whether the result was a
93     /// success or failure in addition to the value or error.
94     public var debugDescription: String {
95         switch self {
96         case .success(let value):
97             return "SUCCESS: \(value)"
98         case .failure(let error):
99             return "FAILURE: \(error)"
100         }
101     }
102 }
103
104 // MARK: - Functional APIs
105
106 extension Result {
107     /// Creates a `Result` instance from the result of a closure.
108     ///
109     /// A failure result is created when the closure throws, and a success result is created when the closure
110     /// succeeds without throwing an error.
111     ///
112     ///     func someString() throws -> String { ... }
113     ///
114     ///     let result = Result(value: {
115     ///         return try someString()
116     ///     })
117     ///
118     ///     // The type of result is Result<String>
119     ///
120     /// The trailing closure syntax is also supported:
121     ///
122     ///     let result = Result { try someString() }
123     ///
124     /// - parameter value: The closure to execute and create the result for.
125     public init(value: () throws -> Value) {
126         do {
127             self = try .success(value())
128         } catch {
129             self = .failure(error)
130         }
131     }
132
133     /// Returns the success value, or throws the failure error.
134     ///
135     ///     let possibleString: Result<String> = .success("success")
136     ///     try print(possibleString.unwrap())
137     ///     // Prints "success"
138     ///
139     ///     let noString: Result<String> = .failure(error)
140     ///     try print(noString.unwrap())
141     ///     // Throws error
142     public func unwrap() throws -> Value {
143         switch self {
144         case .success(let value):
145             return value
146         case .failure(let error):
147             throw error
148         }
149     }
150
151     /// Evaluates the specified closure when the `Result` is a success, passing the unwrapped value as a parameter.
152     ///
153     /// Use the `map` method with a closure that does not throw. For example:
154     ///
155     ///     let possibleData: Result<Data> = .success(Data())
156     ///     let possibleInt = possibleData.map { $0.count }
157     ///     try print(possibleInt.unwrap())
158     ///     // Prints "0"
159     ///
160     ///     let noData: Result<Data> = .failure(error)
161     ///     let noInt = noData.map { $0.count }
162     ///     try print(noInt.unwrap())
163     ///     // Throws error
164     ///
165     /// - parameter transform: A closure that takes the success value of the `Result` instance.
166     ///
167     /// - returns: A `Result` containing the result of the given closure. If this instance is a failure, returns the
168     ///            same failure.
169     public func map<T>(_ transform: (Value) -> T) -> Result<T> {
170         switch self {
171         case .success(let value):
172             return .success(transform(value))
173         case .failure(let error):
174             return .failure(error)
175         }
176     }
177
178     /// Evaluates the specified closure when the `Result` is a success, passing the unwrapped value as a parameter.
179     ///
180     /// Use the `flatMap` method with a closure that may throw an error. For example:
181     ///
182     ///     let possibleData: Result<Data> = .success(Data(...))
183     ///     let possibleObject = possibleData.flatMap {
184     ///         try JSONSerialization.jsonObject(with: $0)
185     ///     }
186     ///
187     /// - parameter transform: A closure that takes the success value of the instance.
188     ///
189     /// - returns: A `Result` containing the result of the given closure. If this instance is a failure, returns the
190     ///            same failure.
191     public func flatMap<T>(_ transform: (Value) throws -> T) -> Result<T> {
192         switch self {
193         case .success(let value):
194             do {
195                 return try .success(transform(value))
196             } catch {
197                 return .failure(error)
198             }
199         case .failure(let error):
200             return .failure(error)
201         }
202     }
203
204     /// Evaluates the specified closure when the `Result` is a failure, passing the unwrapped error as a parameter.
205     ///
206     /// Use the `mapError` function with a closure that does not throw. For example:
207     ///
208     ///     let possibleData: Result<Data> = .failure(someError)
209     ///     let withMyError: Result<Data> = possibleData.mapError { MyError.error($0) }
210     ///
211     /// - Parameter transform: A closure that takes the error of the instance.
212     /// - Returns: A `Result` instance containing the result of the transform. If this instance is a success, returns
213     ///            the same instance.
214     public func mapError<T: Error>(_ transform: (Error) -> T) -> Result {
215         switch self {
216         case .failure(let error):
217             return .failure(transform(error))
218         case .success:
219             return self
220         }
221     }
222
223     /// Evaluates the specified closure when the `Result` is a failure, passing the unwrapped error as a parameter.
224     ///
225     /// Use the `flatMapError` function with a closure that may throw an error. For example:
226     ///
227     ///     let possibleData: Result<Data> = .success(Data(...))
228     ///     let possibleObject = possibleData.flatMapError {
229     ///         try someFailableFunction(taking: $0)
230     ///     }
231     ///
232     /// - Parameter transform: A throwing closure that takes the error of the instance.
233     ///
234     /// - Returns: A `Result` instance containing the result of the transform. If this instance is a success, returns
235     ///            the same instance.
236     public func flatMapError<T: Error>(_ transform: (Error) throws -> T) -> Result {
237         switch self {
238         case .failure(let error):
239             do {
240                 return try .failure(transform(error))
241             } catch {
242                 return .failure(error)
243             }
244         case .success:
245             return self
246         }
247     }
248
249     /// Evaluates the specified closure when the `Result` is a success, passing the unwrapped value as a parameter.
250     ///
251     /// Use the `withValue` function to evaluate the passed closure without modifying the `Result` instance.
252     ///
253     /// - Parameter closure: A closure that takes the success value of this instance.
254     /// - Returns: This `Result` instance, unmodified.
255     @discardableResult
256     public func withValue(_ closure: (Value) -> Void) -> Result {
257         if case let .success(value) = self { closure(value) }
258
259         return self
260     }
261
262     /// Evaluates the specified closure when the `Result` is a failure, passing the unwrapped error as a parameter.
263     ///
264     /// Use the `withError` function to evaluate the passed closure without modifying the `Result` instance.
265     ///
266     /// - Parameter closure: A closure that takes the success value of this instance.
267     /// - Returns: This `Result` instance, unmodified.
268     @discardableResult
269     public func withError(_ closure: (Error) -> Void) -> Result {
270         if case let .failure(error) = self { closure(error) }
271
272         return self
273     }
274
275     /// Evaluates the specified closure when the `Result` is a success.
276     ///
277     /// Use the `ifSuccess` function to evaluate the passed closure without modifying the `Result` instance.
278     ///
279     /// - Parameter closure: A `Void` closure.
280     /// - Returns: This `Result` instance, unmodified.
281     @discardableResult
282     public func ifSuccess(_ closure: () -> Void) -> Result {
283         if isSuccess { closure() }
284
285         return self
286     }
287
288     /// Evaluates the specified closure when the `Result` is a failure.
289     ///
290     /// Use the `ifFailure` function to evaluate the passed closure without modifying the `Result` instance.
291     ///
292     /// - Parameter closure: A `Void` closure.
293     /// - Returns: This `Result` instance, unmodified.
294     @discardableResult
295     public func ifFailure(_ closure: () -> Void) -> Result {
296         if isFailure { closure() }
297
298         return self
299     }
300 }