Skip to content

Instantly share code, notes, and snippets.

@dydus0x14
Created April 26, 2016 07:51
Show Gist options
  • Save dydus0x14/a00e9c4930cf59fafbb1997d9fa6f350 to your computer and use it in GitHub Desktop.
Save dydus0x14/a00e9c4930cf59fafbb1997d9fa6f350 to your computer and use it in GitHub Desktop.
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