0001 // Copyright (c) 2015 Rob Rix. All rights reserved. 0002 0003 /// An enum representing either a failure with an explanatory error, or a success with a result value. 0004 public enum Result<T
Result.swift:22 self = value.map(Result.Success) ?? .Failure(failWith())Result.swift:72 public func recoverWith(@autoclosure result: () -> Result<T,Error>) -> Result<T,Error> {Result.swift:72 public func recoverWith(@autoclosure result: () -> Result<T,Error>) -> Result<T,Error> {Result.swift:132 public func == <T: Equatable, Error: Equatable> (left: Result<T, Error>, right: Result<T, Error>) -> Bool {Result.swift:132 public func == <T: Equatable, Error: Equatable> (left: Result<T, Error>, right: Result<T, Error>) -> Bool {Result.swift:142 public func != <T: Equatable, Error: Equatable> (left: Result<T, Error>, right: Result<T, Error>) -> Bool {Result.swift:142 public func != <T: Equatable, Error: Equatable> (left: Result<T, Error>, right: Result<T, Error>) -> Bool {Result.swift:148 public func ?? <T, Error> (left: Result<T, Error>, @autoclosure right: () -> T) -> T {Result.swift:153 public func ?? <T, Error> (left: Result<T, Error>, @autoclosure right: () -> Result<T, Error>) -> Result<T, Error> {Result.swift:153 public func ?? <T, Error> (left: Result<T, Error>, @autoclosure right: () -> Result<T, Error>) -> Result<T, Error> {Result.swift:153 public func ?? <T, Error> (left: Result<T, Error>, @autoclosure right: () -> Result<T, Error>) -> Result<T, Error> {Result.swift:159 public func materialize<T>(@noescape f: () throws -> T) -> Result<T, NSError> {Result.swift:163 public func materialize<T>(@autoclosure f: () throws -> T) -> Result<T, NSError> {Result.swift:180 public func `try`<T>(function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__, `try`: NSErrorPointer -> T?) -> Result<T, NSError> {Result.swift:182 return `try`(&error).map(Result.Success) ?? .Failure(error ?? Result<T, NSError>.error(function: function, file: file, line: line))Result.swift:182 return `try`(&error).map(Result.Success) ?? .Failure(error ?? Result<T, NSError>.error(function: function, file: file, line: line))Result.swift:190 public func `try`(function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__, `try`: NSErrorPointer -> Bool) -> Result<(), NSError> {Result.swift:194 : .Failure(error ?? Result<(), NSError>.error(function: function, file: file, line: line))Result.swift:212 public func >>- <T, U, Error> (result: Result<T, Error>, @noescape transform: T -> Result<U, Error>) -> Result<U, Error> {Result.swift:212 public func >>- <T, U, Error> (result: Result<T, Error>, @noescape transform: T -> Result<U, Error>) -> Result<U, Error> {Result.swift:212 public func >>- <T, U, Error> (result: Result<T, Error>, @noescape transform: T -> Result<U, Error>) -> Result<U, Error> {ResultType.swift:43 public func map<U>(@noescape transform: Value -> U) -> Result<U, Error> {ResultType.swift:48 public func flatMap<U>(@noescape transform: Value -> Result<U, Error>) -> Result<U, Error> {ResultType.swift:48 public func flatMap<U>(@noescape transform: Value -> Result<U, Error>) -> Result<U, Error> {ResultType.swift:51 ifFailure: Result<U, Error>.Failure)ResultType.swift:55 public func mapError<Error2>(@noescape transform: Error -> Error2) -> Result<Value, Error2> {ResultType.swift:60 public func flatMapError<Error2>(@noescape transform: Error -> Result<Value, Error2>) -> Result<Value, Error2> {ResultType.swift:60 public func flatMapError<Error2>(@noescape transform: Error -> Result<Value, Error2>) -> Result<Value, Error2> {ResultType.swift:62 ifSuccess: Result<Value, Error2>.Success,ResultType.swift:76 public func tryMap<U>(@noescape transform: Value throws -> U) -> Result<U, Error> {ResultType.swift:101 public func &&& <L: ResultType, R: ResultType where L.Error == R.Error> (left: L, @autoclosure right: () -> R) -> Result<(L.Value, R.Value), L.Error> {, Error
Result.swift:5 case Success(T)Result.swift:11 public init(value: T) {Result.swift:21 public init(_ value: T?, @autoclosure failWith: () -> Error) {Result.swift:26 public init(@autoclosure _ f: () throws -> T) {Result.swift:31 public init(@noescape attempt f: () throws -> T) {Result.swift:42 public func dematerialize() throws -> T {Result.swift:54 public func analysis<Result>(@noescape ifSuccess ifSuccess: T -> Result, @noescape ifFailure: Error -> Result) -> Result {Result.swift:67 public func recover(@autoclosure value: () -> T) -> T {Result.swift:67 public func recover(@autoclosure value: () -> T) -> T {Result.swift:72 public func recoverWith(@autoclosure result: () -> Result<T,Error>) -> Result<T,Error> {Result.swift:72 public func recoverWith(@autoclosure result: () -> Result<T,Error>) -> Result<T,Error> {: ErrorType>: ResultType, CustomStringConvertible, CustomDebugStringConvertible { 0005 case Success
Result.swift:6 case Failure(Error)Result.swift:16 public init(error: Error) {Result.swift:21 public init(_ value: T?, @autoclosure failWith: () -> Error) {Result.swift:54 public func analysis<Result>(@noescape ifSuccess ifSuccess: T -> Result, @noescape ifFailure: Error -> Result) -> Result {Result.swift:72 public func recoverWith(@autoclosure result: () -> Result<T,Error>) -> Result<T,Error> {Result.swift:72 public func recoverWith(@autoclosure result: () -> Result<T,Error>) -> Result<T,Error> {(T) 0006 case Failure
Result.swift:12 self = .Success(value)Result.swift:22 self = value.map(Result.Success) ?? .Failure(failWith())Result.swift:33 self = .Success(try f())Result.swift:44 case let .Success(value):Result.swift:56 case let .Success(value):Result.swift:165 return .Success(try f())Result.swift:182 return `try`(&error).map(Result.Success) ?? .Failure(error ?? Result<T, NSError>.error(function: function, file: file, line: line))Result.swift:193 .Success(())ResultType.swift:44 return flatMap { .Success(transform($0)) }ResultType.swift:62 ifSuccess: Result<Value, Error2>.Success,ResultType.swift:79 return .Success(try transform(value))(Error) 0007 0008 // MARK: Constructors 0009 0010 /// Constructs a success wrapping a `value`. 0011 public init(value: T) { 0012 self = .Success(value) 0013 } 0014 0015 /// Constructs a failure wrapping an `error`. 0016 public init(error: Error) { 0017 self = .Failure(error) 0018 } 0019 0020 /// Constructs a result from an Optional, failing with `Error` if `nil`. 0021 public init(_ value: T?, @autoclosure failWith: () -> Error) { 0022 self = value.map(Result.Success) ?? .Failure(failWith()) 0023 } 0024 0025 /// Constructs a result from a function that uses `throw`, failing with `Error` if throws. 0026 public init(@autoclosure _ f: () throws -> T) { 0027 self.init(attempt: f) 0028 } 0029 0030 /// Constructs a result from a function that uses `throw`, failing with `Error` if throws. 0031 public init
Result.swift:17 self = .Failure(error)Result.swift:22 self = value.map(Result.Success) ?? .Failure(failWith())Result.swift:35 self = .Failure(error as! Error)Result.swift:46 case let .Failure(error):Result.swift:58 case let .Failure(value):Result.swift:167 return .Failure(error)Result.swift:182 return `try`(&error).map(Result.Success) ?? .Failure(error ?? Result<T, NSError>.error(function: function, file: file, line: line))Result.swift:194 : .Failure(error ?? Result<(), NSError>.error(function: function, file: file, line: line))ResultType.swift:51 ifFailure: Result<U, Error>.Failure)ResultType.swift:56 return flatMapError { .Failure(transform($0)) }ResultType.swift:84 return .Failure(convertedError)(@noescape attempt f: () throws -> T) { 0032 do { 0033 self = .Success(try f()) 0034 } catch { 0035 self = .Failure(error as! Error) 0036 } 0037 } 0038 0039 // MARK: Deconstruction 0040 0041 /// Returns the value from `Success` Results or `throw`s the error. 0042 public func dematerialize() throws -> T { 0043 switch self { 0044 case let .Success(value): 0045 return value 0046 case let .Failure(error): 0047 throw error 0048 } 0049 } 0050 0051 /// Case analysis for Result. 0052 /// 0053 /// Returns the value produced by applying `ifFailure` to `Failure` Results, or `ifSuccess` to `Success` Results. 0054 public func analysis
Result.swift:27 self.init(attempt: f)<Result>(@noescape ifSuccess ifSuccess: T -> Result, @noescape ifFailure: Error -> Result) -> Result { 0055 switch self { 0056 case let .Success(value): 0057 return ifSuccess(value) 0058 case let .Failure(value): 0059 return ifFailure(value) 0060 } 0061 } 0062 0063 0064 // MARK: Higher-order functions 0065 0066 /// Returns `self.value` if this result is a .Success, or the given value otherwise. Equivalent with `??` 0067 public func recover
Result.swift:73 return analysis(Result.swift:117 return analysis((@autoclosure value: () -> T) -> T { 0068 return self.value ?? value() 0069 } 0070 0071 /// Returns this result if it is a .Success, or the given result otherwise. Equivalent with `??` 0072 public func recoverWith
Result.swift:149 return left.recover(right())(@autoclosure result: () -> Result<T,Error>) -> Result<T,Error> { 0073 return analysis( 0074 ifSuccess: { _ in self }, 0075 ifFailure: { _ in result() }) 0076 } 0077 0078 // MARK: Errors 0079 0080 /// The domain for errors constructed by Result. 0081 public static var errorDomain
Result.swift:154 return left.recoverWith(right()): String { return "com.antitypical.Result" } 0082 0083 /// The userInfo key for source functions in errors constructed by Result. 0084 public static var functionKey
Result.swift:84 public static var functionKey: String { return "\(errorDomain).function" }Result.swift:87 public static var fileKey: String { return "\(errorDomain).file" }Result.swift:90 public static var lineKey: String { return "\(errorDomain).line" }Result.swift:110 return NSError(domain: errorDomain, code: 0, userInfo: userInfo): String { return "\(errorDomain).function" } 0085 0086 /// The userInfo key for source file paths in errors constructed by Result. 0087 public static var fileKey
Result.swift:101 functionKey: function,: String { return "\(errorDomain).file" } 0088 0089 /// The userInfo key for source file line numbers in errors constructed by Result. 0090 public static var lineKey
Result.swift:102 fileKey: file,: String { return "\(errorDomain).line" } 0091 0092 #if os(Linux) 0093 private typealias UserInfoType = Any 0094 #else 0095 private typealias UserInfoType
Result.swift:103 lineKey: line,= AnyObject 0096 #endif 0097 0098 /// Constructs an error. 0099 public static func error
Result.swift:100 var userInfo: [String: UserInfoType] = [(message: String? = nil, function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__) -> NSError { 0100 var userInfo: [String: UserInfoType] = [ 0101 functionKey: function, 0102 fileKey: file, 0103 lineKey: line, 0104 ] 0105 0106 if let message = message { 0107 userInfo[NSLocalizedDescriptionKey] = message 0108 } 0109 0110 return NSError(domain: errorDomain, code: 0, userInfo: userInfo) 0111 } 0112 0113 0114 // MARK: CustomStringConvertible 0115 0116 public var description
Result.swift:182 return `try`(&error).map(Result.Success) ?? .Failure(error ?? Result<T, NSError>.error(function: function, file: file, line: line))Result.swift:194 : .Failure(error ?? Result<(), NSError>.error(function: function, file: file, line: line)): String { 0117 return analysis( 0118 ifSuccess: { ".Success(\($0))" }, 0119 ifFailure: { ".Failure(\($0))" }) 0120 } 0121 0122 0123 // MARK: CustomDebugStringConvertible 0124 0125 public var debugDescription: String { 0126 return description 0127 } 0128 } 0129 0130 0131 /// Returns `true` if `left` and `right` are both `Success`es and their values are equal, or if `left` and `right` are both `Failure`s and their errors are equal. 0132 public func == <T: Equatable, Error: Equatable> (left: Result<T, Error>, right: Result<T, Error>) -> Bool { 0133 if let left = left.value, right = right.value { 0134 return left == right 0135 } else if let left = left.error, right = right.error { 0136 return left == right 0137 } 0138 return false 0139 } 0140 0141 /// Returns `true` if `left` and `right` represent different cases, or if they represent the same case but different values. 0142 public func != <T: Equatable, Error: Equatable> (left: Result<T, Error>, right: Result<T, Error>) -> Bool { 0143 return !(left == right) 0144 } 0145 0146 0147 /// Returns the value of `left` if it is a `Success`, or `right` otherwise. Short-circuits. 0148 public func ?? <T, Error> (left: Result<T, Error>, @autoclosure right: () -> T) -> T { 0149 return left.recover(right()) 0150 } 0151 0152 /// Returns `left` if it is a `Success`es, or `right` otherwise. Short-circuits. 0153 public func ?? <T, Error> (left: Result<T, Error>, @autoclosure right: () -> Result<T, Error>) -> Result<T, Error> { 0154 return left.recoverWith(right()) 0155 } 0156 0157 // MARK: - Derive result from failable closure 0158 0159 public func materialize<T>(@noescape f: () throws -> T) -> Result<T, NSError> { 0160 return materialize(try f()) 0161 } 0162 0163 public func materialize
Result.swift:126 return description<T>(@autoclosure f: () throws -> T) -> Result<T, NSError> { 0164 do { 0165 return .Success(try f()) 0166 } catch let error as NSError { 0167 return .Failure(error) 0168 } 0169 } 0170 0171 // MARK: - Cocoa API conveniences 0172 0173 #if !os(Linux) 0174 0175 /// Constructs a Result with the result of calling `try` with an error pointer. 0176 /// 0177 /// This is convenient for wrapping Cocoa API which returns an object or `nil` + an error, by reference. e.g.: 0178 /// 0179 /// Result.try { NSData(contentsOfURL: URL, options: .DataReadingMapped, error: $0) } 0180 public func `try`<T>(function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__, `try`: NSErrorPointer -> T?) -> Result<T, NSError> { 0181 var error: NSError? 0182 return `try`(&error).map(Result.Success) ?? .Failure(error ?? Result<T, NSError>.error(function: function, file: file, line: line)) 0183 } 0184 0185 /// Constructs a Result with the result of calling `try` with an error pointer. 0186 /// 0187 /// This is convenient for wrapping Cocoa API which returns a `Bool` + an error, by reference. e.g.: 0188 /// 0189 /// Result.try { NSFileManager.defaultManager().removeItemAtURL(URL, error: $0) } 0190 public func `try`(function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__, `try`: NSErrorPointer -> Bool) -> Result<(), NSError> { 0191 var error: NSError? 0192 return `try`(&error) ? 0193 .Success(()) 0194 : .Failure(error ?? Result<(), NSError>.error(function: function, file: file, line: line)) 0195 } 0196 0197 #endif 0198 0199 // MARK: - Operators 0200 0201 infix operator >>- { 0202 // Left-associativity so that chaining works like you’d expect, and for consistency with Haskell, Runes, swiftz, etc. 0203 associativity left 0204 0205 // Higher precedence than function application, but lower than function composition. 0206 precedence 100 0207 } 0208 0209 /// Returns the result of applying `transform` to `Success`es’ values, or re-wrapping `Failure`’s errors. 0210 /// 0211 /// This is a synonym for `flatMap`. 0212 public func >>- <T, U, Error> (result: Result<T, Error>, @noescape transform: T -> Result<U, Error>) -> Result<U, Error> { 0213 return result.flatMap(transform) 0214 } 0215 0216 0217 // MARK: - ErrorTypeConvertible conformance 0218 0219 #if !os(Linux) 0220 0221 /// Make NSError conform to ErrorTypeConvertible 0222 extension NSError: ErrorTypeConvertible { 0223 public static func errorFromErrorType(error: ErrorType) -> NSError { 0224 return error as NSError 0225 } 0226 } 0227 0228 #endif 0229 0230 // MARK: - 0231 0232 /// An “error” that is impossible to construct. 0233 /// 0234 /// This can be used to describe `Result`s where failures will never 0235 /// be generated. For example, `Result<Int, NoError>` describes a result that 0236 /// contains an `Int`eger and is guaranteed never to be a `Failure`. 0237 public enum NoError: ErrorType { } 0238 0239 import Foundation 0240
Result.swift:160 return materialize(try f())