Skip to content

Instantly share code, notes, and snippets.

@icanzilb
Created September 14, 2021 15:36
Show Gist options
  • Save icanzilb/946b03420490cf7ff623a371dd9faa7e to your computer and use it in GitHub Desktop.
Save icanzilb/946b03420490cf7ff623a371dd9faa7e to your computer and use it in GitHub Desktop.
Result initialized with an async operation
extension Result where Failure == Error {
init(_ task: @escaping () async throws -> Success) async {
self = await withCheckedContinuation { [task] continuation in
Task {
do {
continuation.resume(returning: .success(try await task()))
} catch {
continuation.resume(returning: .failure(error))
}
}
}
}
}
@icanzilb
Copy link
Author

icanzilb commented Sep 14, 2021

Or if you need a throwing variant:

extension Result {
  init(_ task: @escaping () async throws -> Success) async throws {
    self = try await withCheckedThrowingContinuation { [task] continuation in
      Task {
        do {
          continuation.resume(returning: .success(try await task()))
        } catch let error as Failure {
          continuation.resume(returning: .failure(error))
        } catch {
          continuation.resume(throwing: error)
        }
      }
    }
  }
}

@aurrak
Copy link

aurrak commented Sep 15, 2021

I am trying to wrap my head around this, is it possible to show an example on how it can be used at the call site?

@icanzilb
Copy link
Author

I am trying to wrap my head around this, is it possible to show an example on how it can be used at the call site?

You get a result out of a throwing async task, like so:

let webResponse = await Result { try await URLSession.shared.data(from: url) }

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