Created
April 26, 2016 07:51
-
-
Save dydus0x14/a00e9c4930cf59fafbb1997d9fa6f350 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum Result<T> { | |
case Success(T) | |
case Failure(ErrorType?) | |
init() { | |
self = .Failure(nil) | |
} | |
init(_ f: () throws->T) { | |
do { | |
self = .Success(try f()) | |
} catch { | |
self = .Failure(error) | |
} | |
} | |
var value: T? { | |
get { | |
switch self { | |
case .Success(let result): | |
return result | |
default: return nil | |
} | |
} | |
} | |
var error: ErrorType? { | |
get { | |
switch self { | |
case .Failure(let result): | |
return result | |
default: return nil | |
} | |
} | |
} | |
} | |
func compare(left: Result<Void>, _ right: Result<Void>) -> Bool { | |
switch (left, right) { | |
case (.Success(_), .Success(_)): return true | |
case (.Failure(nil), .Failure(nil)): return true | |
case (.Failure(let a as ErrorType), .Failure(let b as ErrorType)): return a.dynamicType == b.dynamicType | |
case (.Failure(_), .Failure(_)): return false | |
default: return false | |
} | |
} | |
func compare<T: Equatable>(left: Result<T>, _ right: Result<T>) -> Bool { | |
switch (left, right) { | |
case (.Success(let a), .Success(let b)) where a == b: return true | |
case (.Failure(nil), .Failure(nil)): return true | |
case (.Failure(let a as ErrorType), .Failure(let b as ErrorType)): return a.dynamicType == b.dynamicType | |
case (.Failure(_), .Failure(_)): return false | |
default: return false | |
} | |
} | |
func handle(actual actual: Result<Void>, expected: Result<Void>, @noescape handler: ()->()) -> Result<Void> { | |
if compare(actual, expected) { | |
handler() | |
} | |
return actual | |
} | |
extension Result: CustomStringConvertible { | |
var description: String { | |
switch self { | |
case .Success: | |
return "SUCCESS" | |
case .Failure: | |
return "FAILURE" | |
} | |
} | |
} | |
extension Result where T: Equatable { | |
func handle(expected expected: Result<T>, @noescape handler: ()->()) -> Result<T> { | |
if compare(self, expected) { | |
handler() | |
} | |
return self | |
} | |
} | |
extension Result where T: CollectionType { | |
func forEach(@noescape handler: (T.Generator.Element) throws ->()) -> Result<T> { | |
switch self { | |
case .Success(let collection): | |
do { | |
try collection.forEach({ try handler($0) }) | |
} catch { | |
return .Failure(error) | |
} | |
default: break | |
} | |
return self | |
} | |
func map<U>(@noescape handler: (T.Generator.Element) throws ->(U)) -> Result<[U]> { | |
switch self { | |
case .Success(let collection): | |
do { | |
let newCollection = try collection.map({ try handler($0) }) | |
return Result<[U]>.Success(newCollection) | |
} catch { | |
return .Failure(error) | |
} | |
case .Failure(let error): | |
return .Failure(error) | |
} | |
} | |
func filter(@noescape includeElement: (T.Generator.Element) throws -> Bool) -> Result<[T.Generator.Element]> { | |
switch self { | |
case .Success(let collection): | |
do { | |
let newCollection = try collection.filter({ try includeElement($0) }) | |
return Result<[T.Generator.Element]>.Success(newCollection) | |
} catch { | |
return .Failure(error) | |
} | |
case .Failure(let error): | |
return .Failure(error) | |
} | |
} | |
} | |
extension Result { | |
func handleError(@noescape handler: (ErrorType?) -> ()) -> Result<T> { | |
switch self { | |
case .Failure(let error): handler(error) | |
default: break | |
} | |
return self | |
} | |
func then<U>(f: T throws->U) -> Result<U> { | |
switch self { | |
case .Success(let t): | |
do { | |
let result = try f(t) | |
return .Success(result) | |
} catch { | |
return .Failure(error) | |
} | |
case .Failure(let err): return .Failure(err) | |
} | |
} | |
func then<U>(f: T->Result<U>) -> Result<U> { | |
switch self { | |
case .Success(let t): return f(t) | |
case .Failure(let err): return .Failure(err) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment