-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Support typed throws * Update Sources/ConcurrencyExtras/Result.swift Co-authored-by: Stephen Celis <[email protected]> * Constrain change to compiler(>=6) * Also gate the test to Swift 6 * Include func g in ifdef * wip --------- Co-authored-by: Stephen Celis <[email protected]> Co-authored-by: Stephen Celis <[email protected]>
- Loading branch information
1 parent
d1e4642
commit f5d0abc
Showing
2 changed files
with
87 additions
and
12 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,27 @@ | ||
extension Result where Failure == Swift.Error { | ||
/// Creates a new result by evaluating an async throwing closure, capturing the returned value as | ||
/// a success, or any thrown error as a failure. | ||
/// | ||
/// - Parameter body: A throwing closure to evaluate. | ||
@_transparent | ||
public init(catching body: () async throws -> Success) async { | ||
do { | ||
self = .success(try await body()) | ||
} catch { | ||
self = .failure(error) | ||
#if compiler(>=6) | ||
extension Result { | ||
/// Creates a new result by evaluating an async throwing closure, capturing the returned value as | ||
/// a success, or any thrown error as a failure. | ||
/// | ||
/// - Parameter body: A throwing closure to evaluate. | ||
@_transparent | ||
public init(catching body: () async throws(Failure) -> Success) async { | ||
do { | ||
self = .success(try await body()) | ||
} catch { | ||
self = .failure(error) | ||
} | ||
} | ||
} | ||
} | ||
#else | ||
extension Result where Failure == Swift.Error { | ||
@_transparent | ||
public init(catching body: () async throws -> Success) async { | ||
do { | ||
self = .success(try await body()) | ||
} catch { | ||
self = .failure(error) | ||
} | ||
} | ||
} | ||
#endif |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import ConcurrencyExtras | ||
import XCTest | ||
|
||
final class ResultTests: XCTestCase { | ||
struct SomeError: Error, Equatable { } | ||
func f(_ value: Int) async throws -> Int { | ||
if value == 42 { | ||
return 42 | ||
} else { | ||
throw SomeError() | ||
} | ||
} | ||
|
||
func testBasics() async { | ||
do { | ||
let res = await Result { try await f(42) } | ||
XCTAssertEqual(try res.get(), 42) | ||
} | ||
do { | ||
let res = await Result { try await f(0) } | ||
do { | ||
_ = try res.get() | ||
} catch let error as SomeError { | ||
XCTAssertEqual(error, SomeError()) | ||
} catch { | ||
XCTFail("unexpected error: \(error)") | ||
} | ||
} | ||
} | ||
|
||
#if compiler(>=6) | ||
func g(_ value: Int) async throws(SomeError) -> Int { | ||
if value == 42 { | ||
return 42 | ||
} else { | ||
throw SomeError() | ||
} | ||
} | ||
|
||
func testTypedThrows() async { | ||
let res = await Result { () async throws(SomeError) -> Int in try await g(0) } | ||
do { | ||
_ = try res.get() | ||
} catch { | ||
XCTAssertEqual(error, SomeError()) | ||
} | ||
} | ||
|
||
func h() async throws(SomeError) -> Int { | ||
throw SomeError() | ||
} | ||
|
||
func testTypedThrowsInference() async { | ||
let res = await Result(catching: h) | ||
do { | ||
_ = try res.get() | ||
} catch { | ||
XCTAssertEqual(error, SomeError()) | ||
} | ||
} | ||
#endif | ||
} |