Skip to content
This repository was archived by the owner on Aug 29, 2022. It is now read-only.

Commit febc96f

Browse files
committed
Adds map and flatMap to TaskResult
1 parent 403df55 commit febc96f

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

Sources/Task/ResultRecovery.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,42 @@
66
// Copyright © 2014-2018 Big Nerd Ranch. Licensed under MIT.
77
//
88

9+
extension TaskResult {
10+
/// Evaluates the `transform` for a success result, passing its unwrapped
11+
/// value as the parameter, to derive a new value.
12+
///
13+
/// Use the `map` method with a closure that produces a new value.
14+
public func map<NewValue>(_ transform: (Value) throws -> NewValue) -> TaskResult<NewValue> {
15+
switch self {
16+
case .success(let value):
17+
do {
18+
return try .success(transform(value))
19+
} catch {
20+
return .failure(error)
21+
}
22+
case .failure(let error):
23+
return .failure(error)
24+
}
25+
}
26+
27+
/// Evaluates the `transform` for a success result, passing its unwrapped
28+
/// value as the parameter, to derive a new result.
29+
///
30+
/// Use `flatMap` with a closure that itself returns a result.
31+
public func flatMap<NewValue>(_ transform: (Value) throws -> TaskResult<NewValue>) -> TaskResult<NewValue> {
32+
switch self {
33+
case .success(let value):
34+
do {
35+
return try transform(value)
36+
} catch {
37+
return .failure(error)
38+
}
39+
case .failure(let error):
40+
return .failure(error)
41+
}
42+
}
43+
}
44+
945
extension TaskResult {
1046
/// Performs a coalescing operation, returning the result of unwrapping the
1147
/// success value of `result`, or `defaultValue` in case of an error.

Tests/TaskTests/ResultRecoveryTests.swift

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,67 @@ import Deferred
1717

1818
class ResultRecoveryTests: XCTestCase {
1919
static let allTests: [(String, (ResultRecoveryTests) -> () throws -> Void)] = [
20+
("testMap", testMap),
21+
("testFlatMap", testFlatMap),
2022
("testInitWithFunctionProducesSuccesses", testInitWithFunctionProducesSuccesses),
2123
("testInitWithFunctionProducesFailures", testInitWithFunctionProducesFailures)
2224
]
2325

2426
private typealias Result = Task<String>.Result
2527

28+
private let aSuccessResult = Result(success: "foo")
29+
private let aFailureResult = Result(failure: TestError.first)
30+
31+
func testMap() {
32+
let successResult1: Result = aSuccessResult.map { "\($0)\($0)" }
33+
XCTAssertEqual(try successResult1.extract(), "foofoo")
34+
35+
let successResult2: Result = aSuccessResult.map { _ in throw TestError.second }
36+
XCTAssertThrowsError(try successResult2.extract()) {
37+
XCTAssertEqual($0 as? TestError, .second)
38+
}
39+
40+
let failureResult1: Result = aFailureResult.map { "\($0)\($0)" }
41+
XCTAssertThrowsError(try failureResult1.extract()) {
42+
XCTAssertEqual($0 as? TestError, .first)
43+
}
44+
45+
let failureResult2: Result = aFailureResult.map { _ in throw TestError.second }
46+
XCTAssertThrowsError(try failureResult2.extract()) {
47+
XCTAssertEqual($0 as? TestError, .first)
48+
}
49+
}
50+
51+
func testFlatMap() {
52+
let successResult1: Result = aSuccessResult.flatMap { .success("\($0)\($0)") }
53+
XCTAssertEqual(try successResult1.extract(), "foofoo")
54+
55+
let successResult2: Result = aSuccessResult.flatMap { _ in throw TestError.second }
56+
XCTAssertThrowsError(try successResult2.extract()) {
57+
XCTAssertEqual($0 as? TestError, .second)
58+
}
59+
60+
let successResult3: Result = aSuccessResult.flatMap { _ in .failure(TestError.third) }
61+
XCTAssertThrowsError(try successResult3.extract()) {
62+
XCTAssertEqual($0 as? TestError, .third)
63+
}
64+
65+
let failureResult1: Result = aFailureResult.flatMap { .success("\($0)\($0)") }
66+
XCTAssertThrowsError(try failureResult1.extract()) {
67+
XCTAssertEqual($0 as? TestError, .first)
68+
}
69+
70+
let failureResult2: Result = aFailureResult.flatMap { _ in throw TestError.second }
71+
XCTAssertThrowsError(try failureResult2.extract()) {
72+
XCTAssertEqual($0 as? TestError, .first)
73+
}
74+
75+
let failureResult3: Result = aFailureResult.flatMap { _ in .failure(TestError.third) }
76+
XCTAssertThrowsError(try failureResult3.extract()) {
77+
XCTAssertEqual($0 as? TestError, .first)
78+
}
79+
}
80+
2681
private func tryIsSuccess(_ text: String?) throws -> String {
2782
guard let text = text, text == "success" else {
2883
throw TestError.first

0 commit comments

Comments
 (0)