// // Result+Alamofire.swift // // Copyright (c) 2019 Alamofire Software Foundation (http://alamofire.org/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // import Foundation /// Default type of `Result` returned by Alamofire, with an `AFError` `Failure` type. public typealias AFResult = Result // MARK: - Internal APIs extension Result { /// Returns whether the instance is `.success`. var isSuccess: Bool { guard case .success = self else { return false } return true } /// Returns whether the instance is `.failure`. var isFailure: Bool { !isSuccess } /// Returns the associated value if the result is a success, `nil` otherwise. var success: Success? { guard case let .success(value) = self else { return nil } return value } /// Returns the associated error value if the result is a failure, `nil` otherwise. var failure: Failure? { guard case let .failure(error) = self else { return nil } return error } /// Initializes a `Result` from value or error. Returns `.failure` if the error is non-nil, `.success` otherwise. /// /// - Parameters: /// - value: A value. /// - error: An `Error`. init(value: Success, error: Failure?) { if let error = error { self = .failure(error) } else { self = .success(value) } } /// Evaluates the specified closure when the `Result` is a success, passing the unwrapped value as a parameter. /// /// Use the `tryMap` method with a closure that may throw an error. For example: /// /// let possibleData: Result = .success(Data(...)) /// let possibleObject = possibleData.tryMap { /// try JSONSerialization.jsonObject(with: $0) /// } /// /// - parameter transform: A closure that takes the success value of the instance. /// /// - returns: A `Result` containing the result of the given closure. If this instance is a failure, returns the /// same failure. func tryMap(_ transform: (Success) throws -> NewSuccess) -> Result { switch self { case let .success(value): do { return try .success(transform(value)) } catch { return .failure(error) } case let .failure(error): return .failure(error) } } /// Evaluates the specified closure when the `Result` is a failure, passing the unwrapped error as a parameter. /// /// Use the `tryMapError` function with a closure that may throw an error. For example: /// /// let possibleData: Result = .success(Data(...)) /// let possibleObject = possibleData.tryMapError { /// try someFailableFunction(taking: $0) /// } /// /// - Parameter transform: A throwing closure that takes the error of the instance. /// /// - Returns: A `Result` instance containing the result of the transform. If this instance is a success, returns /// the same success. func tryMapError(_ transform: (Failure) throws -> NewFailure) -> Result { switch self { case let .failure(error): do { return try .failure(transform(error)) } catch { return .failure(error) } case let .success(value): return .success(value) } } }