Skip to content

Instantly share code, notes, and snippets.

@jegnux
Last active December 10, 2023 19:24
Show Gist options
  • Save jegnux/500b0975375ebd59c7df039c575d51f2 to your computer and use it in GitHub Desktop.
Save jegnux/500b0975375ebd59c7df039c575d51f2 to your computer and use it in GitHub Desktop.
extension Result {
public func `catch`(_ handler: () throws -> Success) -> Result<Success, Error> {
flatMapError { _ in
.init { try handler() }
}
}
public func `catch`(_ handler: (Failure) throws -> Success) -> Result<Success, Error> {
flatMapError { error in
.init { try handler(error) }
}
}
public func get(default defaultValue: @autoclosure () -> Success) -> Success {
self.default(defaultValue)
}
public func `default`(_ handler: () -> Success) -> Success {
self.default { _ in handler() }
}
public func `default`(_ handler: (Failure) -> Success) -> Success {
switch self {
case .success(let success):
return success
case .failure(let error):
return handler(error)
}
}
}
@jegnux
Copy link
Author

jegnux commented Mar 17, 2021

Examples

Try all blocks in cascade until getting a success and extract the value, or throw if all blocks fail

let result: Int = try Result {
  try doThisFirst()
}.catch {
  try doThisIfFirstFails()
}.catch {
  try doThisIfSecondFails()
}.get()
Compare with regular do/catch
let result: Int 
do {
  result = try doThisFirst()
} catch {
  do {
    result = try doThisIfFirstFails()
  } catch {
    result = try doThisIfSecondFails()
  }
}

Try all blocks in cascade until getting a success and extract the value, or return the default value if all blocks fail

let result: Int = Result {
  try doThisFirst()
}.catch {
  try doThisIfFirstFails()
}.catch {
  try doThisIfSecondFails()
}.get(default: 42)
Compare with regular do/catch
let result: Int 
do {
  result = try doThisFirst()
} catch {
  do {
    result = try doThisIfFirstFails()
  } catch {
    do {
      result = try doThisIfSecondFails()
    } catch {
      result = 42
    }
  }
}

Try all blocks in cascade until getting a success and extract the value, or return the value from the non-throwing default block

let result: Int = Result {
  try doThisFirst()
}.catch {
  try doThisIfFirstFails()
}.catch {
  try doThisIfSecondFails()
}.default {
  doThisIfAllFail()
}
Compare with regular do/catch
let result: Int 
do {
  result = try doThisFirst()
} catch {
  do {
    result = try doThisIfFirstFails()
  } catch {
    do {
      result = try doThisIfSecondFails()
    } catch {
      result = doThisIfAllFail()
    }
  }
}

Thanks

Thanks @ABridoux for the help

@ABridoux
Copy link

👌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment