Permalink
Switch branches/tags
swift-DEVELOPMENT-SNAPSHOT-2018-11-14-a swift-DEVELOPMENT-SNAPSHOT-2018-11-13-a swift-DEVELOPMENT-SNAPSHOT-2018-11-01-a swift-DEVELOPMENT-SNAPSHOT-2018-10-24-a swift-DEVELOPMENT-SNAPSHOT-2018-10-23-a swift-DEVELOPMENT-SNAPSHOT-2018-10-22-a swift-DEVELOPMENT-SNAPSHOT-2018-10-21-a swift-DEVELOPMENT-SNAPSHOT-2018-10-20-a swift-DEVELOPMENT-SNAPSHOT-2018-10-19-a swift-DEVELOPMENT-SNAPSHOT-2018-10-03-a swift-DEVELOPMENT-SNAPSHOT-2018-10-02-a swift-DEVELOPMENT-SNAPSHOT-2018-10-01-a swift-DEVELOPMENT-SNAPSHOT-2018-09-28-a swift-DEVELOPMENT-SNAPSHOT-2018-09-27-a swift-DEVELOPMENT-SNAPSHOT-2018-09-22-a swift-DEVELOPMENT-SNAPSHOT-2018-09-21-a swift-DEVELOPMENT-SNAPSHOT-2018-09-20-a swift-DEVELOPMENT-SNAPSHOT-2018-09-19-a swift-DEVELOPMENT-SNAPSHOT-2018-09-18-a swift-DEVELOPMENT-SNAPSHOT-2018-09-14-a swift-DEVELOPMENT-SNAPSHOT-2018-09-13-a swift-DEVELOPMENT-SNAPSHOT-2018-09-10-a swift-DEVELOPMENT-SNAPSHOT-2018-09-08-a swift-DEVELOPMENT-SNAPSHOT-2018-09-07-a swift-DEVELOPMENT-SNAPSHOT-2018-09-04-a swift-DEVELOPMENT-SNAPSHOT-2018-08-25-a swift-DEVELOPMENT-SNAPSHOT-2018-08-24-a swift-DEVELOPMENT-SNAPSHOT-2018-08-23-a swift-DEVELOPMENT-SNAPSHOT-2018-08-22-a swift-DEVELOPMENT-SNAPSHOT-2018-08-21-a swift-DEVELOPMENT-SNAPSHOT-2018-08-20-a swift-DEVELOPMENT-SNAPSHOT-2018-08-18-a swift-DEVELOPMENT-SNAPSHOT-2018-08-16-a swift-DEVELOPMENT-SNAPSHOT-2018-08-15-a swift-DEVELOPMENT-SNAPSHOT-2018-08-14-a swift-DEVELOPMENT-SNAPSHOT-2018-08-10-a swift-DEVELOPMENT-SNAPSHOT-2018-08-09-a swift-DEVELOPMENT-SNAPSHOT-2018-08-06-a swift-DEVELOPMENT-SNAPSHOT-2018-08-02-a swift-DEVELOPMENT-SNAPSHOT-2018-08-01-a swift-DEVELOPMENT-SNAPSHOT-2018-07-31-a swift-DEVELOPMENT-SNAPSHOT-2018-07-30-a swift-DEVELOPMENT-SNAPSHOT-2018-07-28-a swift-DEVELOPMENT-SNAPSHOT-2018-07-27-a swift-DEVELOPMENT-SNAPSHOT-2018-07-24-a swift-DEVELOPMENT-SNAPSHOT-2018-07-23-a swift-DEVELOPMENT-SNAPSHOT-2018-07-22-a swift-DEVELOPMENT-SNAPSHOT-2018-07-21-a swift-DEVELOPMENT-SNAPSHOT-2018-07-20-a swift-DEVELOPMENT-SNAPSHOT-2018-07-19-a swift-DEVELOPMENT-SNAPSHOT-2018-07-18-a swift-DEVELOPMENT-SNAPSHOT-2018-07-17-a swift-DEVELOPMENT-SNAPSHOT-2018-07-16-a swift-DEVELOPMENT-SNAPSHOT-2018-07-14-a swift-DEVELOPMENT-SNAPSHOT-2018-07-13-a swift-DEVELOPMENT-SNAPSHOT-2018-07-12-a swift-DEVELOPMENT-SNAPSHOT-2018-07-11-a swift-DEVELOPMENT-SNAPSHOT-2018-07-09-a swift-DEVELOPMENT-SNAPSHOT-2018-07-07-a swift-DEVELOPMENT-SNAPSHOT-2018-07-06-a swift-DEVELOPMENT-SNAPSHOT-2018-07-05-a swift-DEVELOPMENT-SNAPSHOT-2018-07-04-a swift-DEVELOPMENT-SNAPSHOT-2018-07-03-a swift-DEVELOPMENT-SNAPSHOT-2018-07-02-a swift-DEVELOPMENT-SNAPSHOT-2018-07-01-a swift-DEVELOPMENT-SNAPSHOT-2018-06-30-a swift-DEVELOPMENT-SNAPSHOT-2018-06-29-a swift-DEVELOPMENT-SNAPSHOT-2018-06-27-a swift-DEVELOPMENT-SNAPSHOT-2018-06-26-a swift-DEVELOPMENT-SNAPSHOT-2018-06-25-a swift-DEVELOPMENT-SNAPSHOT-2018-06-24-a swift-DEVELOPMENT-SNAPSHOT-2018-06-23-a swift-DEVELOPMENT-SNAPSHOT-2018-06-22-a swift-DEVELOPMENT-SNAPSHOT-2018-06-21-a swift-DEVELOPMENT-SNAPSHOT-2018-06-20-a swift-DEVELOPMENT-SNAPSHOT-2018-06-19-a swift-DEVELOPMENT-SNAPSHOT-2018-06-18-a swift-DEVELOPMENT-SNAPSHOT-2018-06-17-a swift-DEVELOPMENT-SNAPSHOT-2018-06-16-a swift-DEVELOPMENT-SNAPSHOT-2018-06-15-a swift-DEVELOPMENT-SNAPSHOT-2018-06-14-a swift-DEVELOPMENT-SNAPSHOT-2018-06-08-a swift-DEVELOPMENT-SNAPSHOT-2018-06-07-a swift-DEVELOPMENT-SNAPSHOT-2018-06-06-a swift-DEVELOPMENT-SNAPSHOT-2018-06-05-a swift-DEVELOPMENT-SNAPSHOT-2018-06-04-a swift-DEVELOPMENT-SNAPSHOT-2018-06-03-a swift-DEVELOPMENT-SNAPSHOT-2018-06-02-a swift-DEVELOPMENT-SNAPSHOT-2018-06-01-a swift-DEVELOPMENT-SNAPSHOT-2018-05-31-a swift-DEVELOPMENT-SNAPSHOT-2018-05-30-a swift-DEVELOPMENT-SNAPSHOT-2018-05-29-a swift-DEVELOPMENT-SNAPSHOT-2018-05-28-a swift-DEVELOPMENT-SNAPSHOT-2018-05-27-a swift-DEVELOPMENT-SNAPSHOT-2018-05-26-a swift-DEVELOPMENT-SNAPSHOT-2018-05-25-a swift-DEVELOPMENT-SNAPSHOT-2018-05-24-a swift-DEVELOPMENT-SNAPSHOT-2018-05-23-a swift-DEVELOPMENT-SNAPSHOT-2018-05-22-a swift-DEVELOPMENT-SNAPSHOT-2018-05-21-a
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
200 lines (173 sloc) 6.38 KB
/*
This source file is part of the Swift.org open source project
Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception
See http://swift.org/LICENSE.txt for license information
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
/// An simple enum which is either a value or an error.
/// It can be used for error handling in situations where try catch is
/// problematic to use, for eg: asynchronous APIs.
public enum Result<Value, ErrorType: Swift.Error> {
/// Indicates success with value in the associated object.
case success(Value)
/// Indicates failure with error inside the associated object.
case failure(ErrorType)
/// Initialiser for value.
public init(_ value: Value) {
self = .success(value)
}
/// Initialiser for error.
public init(_ error: ErrorType) {
self = .failure(error)
}
/// Initialise with something that can throw ErrorType.
public init(_ body: () throws -> Value) throws {
do {
self = .success(try body())
} catch let error as ErrorType {
self = .failure(error)
}
}
/// Get the value if success else throw the saved error.
public func dematerialize() throws -> Value {
switch self {
case .success(let value):
return value
case .failure(let error):
throw error
}
}
/// Evaluates the given closure when this Result instance has a value.
public func map<U>(_ transform: (Value) throws -> U) rethrows -> Result<U, ErrorType> {
switch self {
case .success(let value):
return Result<U, ErrorType>(try transform(value))
case .failure(let error):
return Result<U, ErrorType>(error)
}
}
/// Evaluates the given closure when this Result instance has a value, passing the unwrapped value as a parameter.
///
/// The closure returns a Result instance itself which can have value or not.
public func flatMap<U>(_ transform: (Value) -> Result<U, ErrorType>) -> Result<U, ErrorType> {
switch self {
case .success(let value):
return transform(value)
case .failure(let error):
return Result<U, ErrorType>(error)
}
}
}
extension Result: CustomStringConvertible {
public var description: String {
switch self {
case .success(let value):
return "Result(\(value))"
case .failure(let error):
return "Result(\(error))"
}
}
}
/// A type erased error enum.
public struct AnyError: Swift.Error, CustomStringConvertible {
/// The underlying error.
public let underlyingError: Swift.Error
public init(_ error: Swift.Error) {
// If we already have any error, don't nest it.
if case let error as AnyError = error {
self = error
} else {
self.underlyingError = error
}
}
public var description: String {
return String(describing: underlyingError)
}
}
/// Represents a string error.
public struct StringError: Equatable, Codable, CustomStringConvertible, Error {
/// The description of the error.
public let description: String
/// Create an instance of StringError.
public init(_ description: String) {
self.description = description
}
}
// AnyError specific helpers.
extension Result where ErrorType == AnyError {
/// Initialise with something that throws AnyError.
public init(anyError body: () throws -> Value) {
do {
self = .success(try body())
} catch {
self = .failure(AnyError(error))
}
}
/// Initialise with an error, it will be automatically converted to AnyError.
public init(_ error: Swift.Error) {
self = .failure(AnyError(error))
}
/// Evaluates the given throwing closure when this Result instance has a value.
///
/// The final result will either be the transformed value or any error thrown by the closure.
public func mapAny<U>(_ transform: (Value) throws -> U) -> Result<U, AnyError> {
switch self {
case .success(let value):
do {
return Result<U, AnyError>(try transform(value))
} catch {
return Result<U, AnyError>(error)
}
case .failure(let error):
return Result<U, AnyError>(error)
}
}
}
extension Result where ErrorType == StringError {
/// Create an instance of Result<Value, StringError>.
///
/// Errors will be encoded as StringError using their description.
public init(string body: () throws -> Value) {
do {
self = .success(try body())
} catch let error as StringError {
self = .failure(error)
} catch {
self = .failure(StringError(String(describing: error)))
}
}
}
extension Result: Equatable where Value: Equatable, ErrorType: Equatable {}
extension Result: Codable where Value: Codable, ErrorType: Codable {
private enum CodingKeys: String, CodingKey {
case success, failure
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case .success(let value):
var unkeyedContainer = container.nestedUnkeyedContainer(forKey: .success)
try unkeyedContainer.encode(value)
case .failure(let error):
var unkeyedContainer = container.nestedUnkeyedContainer(forKey: .failure)
try unkeyedContainer.encode(error)
}
}
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
guard let key = values.allKeys.first(where: values.contains) else {
throw DecodingError.dataCorrupted(.init(codingPath: decoder.codingPath, debugDescription: "Did not find a matching key"))
}
switch key {
case .success:
var unkeyedValues = try values.nestedUnkeyedContainer(forKey: key)
let value = try unkeyedValues.decode(Value.self)
self = .success(value)
case .failure:
var unkeyedValues = try values.nestedUnkeyedContainer(forKey: key)
let error = try unkeyedValues.decode(ErrorType.self)
self = .failure(error)
}
}
}