Skip to content

Commit 6b69976

Browse files
M0rtyMerrfreak4pc
authored andcommitted
Simpify filterMap implementation, add throws to transform closure signature (#214)
1 parent af6764d commit 6b69976

File tree

5 files changed

+86
-27
lines changed

5 files changed

+86
-27
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ Changelog
33

44
- added `reachedBottom(offset:)` for `UIScrollView`
55
- `once` now uses a `NSRecursiveLock` instead of the deprecated `OSAtomicOr32OrigBarrier`
6+
- Simplify `filterMap(_:)` implementation and make callback throwing
7+
- `once` now uses a `NSRecursiveLock` instead of the deprecated `OSAtomicOr32OrigBarrier`
68
- added `merge(with:)` for `Observable`
79

810
5.0.0

RxSwiftExt.xcodeproj/project.pbxproj

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@
103103
62512C781F0EAF950083A89F /* repeatWithBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 538607A71E6F334B000361DE /* repeatWithBehavior.swift */; };
104104
62512C791F0EAF950083A89F /* retryWithBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 538607A81E6F334B000361DE /* retryWithBehavior.swift */; };
105105
62512C7A1F0EAF950083A89F /* unwrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 538607A91E6F334B000361DE /* unwrap.swift */; };
106-
62512C7B1F0EAF950083A89F /* flatMapSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98309EAE1EDF14AC00BD07D9 /* flatMapSync.swift */; };
107106
62512C7C1F0EAF950083A89F /* filterMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98309EB01EDF159500BD07D9 /* filterMap.swift */; };
108107
62512C891F0EB1280083A89F /* RxSwiftExt.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 62512C5E1F0EAF200083A89F /* RxSwiftExt.framework */; };
109108
62512C8F1F0EB17A0083A89F /* DistinctTests+RxCocoa.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F336E91E70D59000D35D38 /* DistinctTests+RxCocoa.swift */; };
@@ -143,6 +142,9 @@
143142
780CB21F20A0EE8300FD3F39 /* MapManyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780CB21C20A0EE8300FD3F39 /* MapManyTests.swift */; };
144143
78199613228449CA00340AF4 /* UIScrollView+reachedBottom.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78199612228449CA00340AF4 /* UIScrollView+reachedBottom.swift */; };
145144
7819961622844EF800340AF4 /* UIScrollView+reachedBottomTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7819961422844E9D00340AF4 /* UIScrollView+reachedBottomTests.swift */; };
145+
782485B7229952FD005CF8CC /* TestErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 782485B6229952FD005CF8CC /* TestErrors.swift */; };
146+
782485B8229952FD005CF8CC /* TestErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 782485B6229952FD005CF8CC /* TestErrors.swift */; };
147+
782485B9229952FD005CF8CC /* TestErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 782485B6229952FD005CF8CC /* TestErrors.swift */; };
146148
782485932298A708005CF8CC /* mergeWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 782485922298A702005CF8CC /* mergeWith.swift */; };
147149
782485952298A785005CF8CC /* MergeWithTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 782485942298A785005CF8CC /* MergeWithTests.swift */; };
148150
782485962298A785005CF8CC /* MergeWithTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 782485942298A785005CF8CC /* MergeWithTests.swift */; };
@@ -151,11 +153,13 @@
151153
7824859C2298ADE2005CF8CC /* mergeWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 782485922298A702005CF8CC /* mergeWith.swift */; };
152154
789682E720408A7500545396 /* mapAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CF5F8B2202D6C5F00C1BA97 /* mapAt.swift */; };
153155
789682E820408A7700545396 /* mapAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CF5F8B2202D6C5F00C1BA97 /* mapAt.swift */; };
156+
789A2A9C22A53F1E00548EF9 /* flatMapSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789A2A9B22A53F1E00548EF9 /* flatMapSync.swift */; };
157+
789A2A9D22A53F1E00548EF9 /* flatMapSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789A2A9B22A53F1E00548EF9 /* flatMapSync.swift */; };
158+
789A2A9E22A53F1E00548EF9 /* flatMapSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789A2A9B22A53F1E00548EF9 /* flatMapSync.swift */; };
154159
8CF5F8AF202D62AB00C1BA97 /* MapAtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CF5F8AD202D622000C1BA97 /* MapAtTests.swift */; };
155160
8CF5F8B0202D62AD00C1BA97 /* MapAtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CF5F8AD202D622000C1BA97 /* MapAtTests.swift */; };
156161
8CF5F8B1202D62AE00C1BA97 /* MapAtTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CF5F8AD202D622000C1BA97 /* MapAtTests.swift */; };
157162
8CF5F8B3202D6C5F00C1BA97 /* mapAt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CF5F8B2202D6C5F00C1BA97 /* mapAt.swift */; };
158-
98309EAF1EDF14AC00BD07D9 /* flatMapSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98309EAE1EDF14AC00BD07D9 /* flatMapSync.swift */; };
159163
98309EB11EDF159500BD07D9 /* filterMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98309EB01EDF159500BD07D9 /* filterMap.swift */; };
160164
98309EB41EDF167300BD07D9 /* FilterMapTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98309EB21EDF161700BD07D9 /* FilterMapTests.swift */; };
161165
A23E148721A9EFC000CD5B2F /* partition.swift in Sources */ = {isa = PBXBuildFile; fileRef = A23E148621A9EFC000CD5B2F /* partition.swift */; };
@@ -230,7 +234,6 @@
230234
E39C41E91F18B08A007F2ACD /* repeatWithBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 538607A71E6F334B000361DE /* repeatWithBehavior.swift */; };
231235
E39C41EA1F18B08A007F2ACD /* retryWithBehavior.swift in Sources */ = {isa = PBXBuildFile; fileRef = 538607A81E6F334B000361DE /* retryWithBehavior.swift */; };
232236
E39C41EB1F18B08A007F2ACD /* unwrap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 538607A91E6F334B000361DE /* unwrap.swift */; };
233-
E39C41EC1F18B08A007F2ACD /* flatMapSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98309EAE1EDF14AC00BD07D9 /* flatMapSync.swift */; };
234237
E39C41ED1F18B08A007F2ACD /* filterMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98309EB01EDF159500BD07D9 /* filterMap.swift */; };
235238
E39C41F71F18B0EA007F2ACD /* RxSwiftExt.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E39C41D01F18AF84007F2ACD /* RxSwiftExt.framework */; };
236239
E39C41FD1F18B13A007F2ACD /* DistinctTests+RxCocoa.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F336E91E70D59000D35D38 /* DistinctTests+RxCocoa.swift */; };
@@ -359,11 +362,12 @@
359362
780CB21C20A0EE8300FD3F39 /* MapManyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MapManyTests.swift; sourceTree = "<group>"; };
360363
78199612228449CA00340AF4 /* UIScrollView+reachedBottom.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIScrollView+reachedBottom.swift"; sourceTree = "<group>"; };
361364
7819961422844E9D00340AF4 /* UIScrollView+reachedBottomTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIScrollView+reachedBottomTests.swift"; sourceTree = "<group>"; };
365+
782485B6229952FD005CF8CC /* TestErrors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TestErrors.swift; path = Tests/TestErrors.swift; sourceTree = "<group>"; };
366+
789A2A9B22A53F1E00548EF9 /* flatMapSync.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = flatMapSync.swift; sourceTree = "<group>"; };
362367
782485922298A702005CF8CC /* mergeWith.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = mergeWith.swift; sourceTree = "<group>"; };
363368
782485942298A785005CF8CC /* MergeWithTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MergeWithTests.swift; sourceTree = "<group>"; };
364369
8CF5F8AD202D622000C1BA97 /* MapAtTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapAtTests.swift; sourceTree = "<group>"; };
365370
8CF5F8B2202D6C5F00C1BA97 /* mapAt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = mapAt.swift; sourceTree = "<group>"; };
366-
98309EAE1EDF14AC00BD07D9 /* flatMapSync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = flatMapSync.swift; path = Source/RxSwift/flatMapSync.swift; sourceTree = SOURCE_ROOT; };
367371
98309EB01EDF159500BD07D9 /* filterMap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = filterMap.swift; path = Source/RxSwift/filterMap.swift; sourceTree = SOURCE_ROOT; };
368372
98309EB21EDF161700BD07D9 /* FilterMapTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FilterMapTests.swift; sourceTree = "<group>"; };
369373
9DAB77851D67639C007E85BC /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Source/Info.plist; sourceTree = SOURCE_ROOT; };
@@ -490,6 +494,7 @@
490494
3D638DF21DC2B2EE0089A590 /* Tests */ = {
491495
isa = PBXGroup;
492496
children = (
497+
782485B6229952FD005CF8CC /* TestErrors.swift */,
493498
3DB034F61DC376D9002C6A26 /* Info.plist */,
494499
538607701E6F1C38000361DE /* RxCocoa */,
495500
538607BA1E6F362B000361DE /* RxSwift */,
@@ -537,7 +542,7 @@
537542
B69B45482190C27D00F30418 /* count.swift */,
538543
5386079D1E6F334B000361DE /* distinct.swift */,
539544
98309EB01EDF159500BD07D9 /* filterMap.swift */,
540-
98309EAE1EDF14AC00BD07D9 /* flatMapSync.swift */,
545+
789A2A9B22A53F1E00548EF9 /* flatMapSync.swift */,
541546
BF515CE11F3F371600492640 /* fromAsync.swift */,
542547
5386079E1E6F334B000361DE /* ignore.swift */,
543548
5386079F1E6F334B000361DE /* ignoreErrors.swift */,
@@ -1042,11 +1047,11 @@
10421047
3DBDE5FC1FBBAE3A00DF47F9 /* and.swift in Sources */,
10431048
8CF5F8B3202D6C5F00C1BA97 /* mapAt.swift in Sources */,
10441049
538607B31E6F334B000361DE /* not.swift in Sources */,
1050+
789A2A9C22A53F1E00548EF9 /* flatMapSync.swift in Sources */,
10451051
B69B45492190C27D00F30418 /* count.swift in Sources */,
10461052
538607AD1E6F334B000361DE /* distinct.swift in Sources */,
10471053
D7C72A421FDC5D8F00EAAAAB /* nwise.swift in Sources */,
10481054
538607B61E6F334B000361DE /* pausable.swift in Sources */,
1049-
98309EAF1EDF14AC00BD07D9 /* flatMapSync.swift in Sources */,
10501055
780CB21520A0ED1C00FD3F39 /* toSortedArray.swift in Sources */,
10511056
E62D9D582199D1EF006636D7 /* bufferWithTrigger.swift in Sources */,
10521057
98309EB11EDF159500BD07D9 /* filterMap.swift in Sources */,
@@ -1076,6 +1081,7 @@
10761081
53F336EA1E70D59000D35D38 /* DistinctTests+RxCocoa.swift in Sources */,
10771082
98309EB41EDF167300BD07D9 /* FilterMapTests.swift in Sources */,
10781083
B69B454E2190C3CC00F30418 /* CountTests.swift in Sources */,
1084+
782485B7229952FD005CF8CC /* TestErrors.swift in Sources */,
10791085
6662395E1E9E0950009BB134 /* Materialized+elementsTests.swift in Sources */,
10801086
538607E81E6F36A9000361DE /* NotTests.swift in Sources */,
10811087
BF515CE51F3F3AF400492640 /* FromAsyncTests.swift in Sources */,
@@ -1132,6 +1138,7 @@
11321138
62512C771F0EAF950083A89F /* pausableBuffered.swift in Sources */,
11331139
62512C761F0EAF950083A89F /* pausable.swift in Sources */,
11341140
62512C721F0EAF950083A89F /* materialized+elements.swift in Sources */,
1141+
789A2A9D22A53F1E00548EF9 /* flatMapSync.swift in Sources */,
11351142
C4D2154520118FC1009804AE /* ofType.swift in Sources */,
11361143
62512C6E1F0EAF950083A89F /* ignore.swift in Sources */,
11371144
3D11958B1FCAD9AE0095134B /* and.swift in Sources */,
@@ -1140,7 +1147,6 @@
11401147
D7C72A431FDC5D8F00EAAAAB /* nwise.swift in Sources */,
11411148
62512C6D1F0EAF950083A89F /* distinct.swift in Sources */,
11421149
62512C7C1F0EAF950083A89F /* filterMap.swift in Sources */,
1143-
62512C7B1F0EAF950083A89F /* flatMapSync.swift in Sources */,
11441150
62512C681F0EAF850083A89F /* mapTo+RxCocoa.swift in Sources */,
11451151
62512C791F0EAF950083A89F /* retryWithBehavior.swift in Sources */,
11461152
DC612873209E80810053CBB7 /* mapMany.swift in Sources */,
@@ -1194,6 +1200,7 @@
11941200
62512C921F0EB1850083A89F /* ApplyTests.swift in Sources */,
11951201
62512CA21F0EB1850083A89F /* WeakTarget.swift in Sources */,
11961202
62512C9D1F0EB1850083A89F /* PausableTests.swift in Sources */,
1203+
782485B8229952FD005CF8CC /* TestErrors.swift in Sources */,
11971204
62512C991F0EB1850083A89F /* MapToTests.swift in Sources */,
11981205
3DBDE6001FBBB09A00DF47F9 /* AndTests.swift in Sources */,
11991206
58C54302EC14B6FF2034BAF6 /* ZipWithTest.swift in Sources */,
@@ -1219,6 +1226,7 @@
12191226
E39C41E81F18B08A007F2ACD /* pausableBuffered.swift in Sources */,
12201227
E39C41E71F18B08A007F2ACD /* pausable.swift in Sources */,
12211228
E39C41E31F18B08A007F2ACD /* materialized+elements.swift in Sources */,
1229+
789A2A9E22A53F1E00548EF9 /* flatMapSync.swift in Sources */,
12221230
C4D2154620118FC1009804AE /* ofType.swift in Sources */,
12231231
E39C41DF1F18B08A007F2ACD /* ignore.swift in Sources */,
12241232
3D11958C1FCAD9AF0095134B /* and.swift in Sources */,
@@ -1227,7 +1235,6 @@
12271235
D7C72A441FDC5D8F00EAAAAB /* nwise.swift in Sources */,
12281236
E39C41DE1F18B08A007F2ACD /* distinct.swift in Sources */,
12291237
E39C41ED1F18B08A007F2ACD /* filterMap.swift in Sources */,
1230-
E39C41EC1F18B08A007F2ACD /* flatMapSync.swift in Sources */,
12311238
E39C41D91F18B086007F2ACD /* mapTo+RxCocoa.swift in Sources */,
12321239
E39C41EA1F18B08A007F2ACD /* retryWithBehavior.swift in Sources */,
12331240
DC612874209E80810053CBB7 /* mapMany.swift in Sources */,
@@ -1281,6 +1288,7 @@
12811288
E39C420D1F18B13E007F2ACD /* RepeatWithBehaviorTests.swift in Sources */,
12821289
E39C42091F18B13E007F2ACD /* NotTests.swift in Sources */,
12831290
E39C42081F18B13E007F2ACD /* Materialized+elementsTests.swift in Sources */,
1291+
782485B9229952FD005CF8CC /* TestErrors.swift in Sources */,
12841292
E39C42071F18B13E007F2ACD /* MapToTests.swift in Sources */,
12851293
3DBDE6011FBBB09A00DF47F9 /* AndTests.swift in Sources */,
12861294
58C54B6E1B4C678DE2378145 /* ZipWithTest.swift in Sources */,

Source/RxSwift/filterMap.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,25 @@ import RxSwift
1111
public enum FilterMap<Result> {
1212
case ignore
1313
case map(Result)
14-
15-
fileprivate var asOperator: AnyOperator<Result> {
16-
switch self {
17-
case .ignore: return .filter
18-
case .map(let value): return .map(value)
19-
}
20-
}
2114
}
2215

2316
extension ObservableType {
2417

2518
/**
2619
Filters or Maps values from the source.
27-
- The returned Observable will error and complete with the source.
20+
- The returned Observable will complete with the source. It will error with the source or with error thrown by transform callback.
2821
- `next` values will be output according to the `transform` callback result:
2922
- returning `.ignore` will filter the value out of the returned Observable
3023
- returning `.map(newValue)` will propagate newValue through the returned Observable.
3124
*/
32-
public func filterMap<Result>(_ transform: @escaping (Element) -> FilterMap<Result>) -> Observable<Result> {
33-
return flatMapSync { transform($0).asOperator }
25+
public func filterMap<Result>(_ transform: @escaping (Element) throws -> FilterMap<Result>) -> Observable<Result> {
26+
return flatMap { element -> Observable<Result> in
27+
switch try transform(element) {
28+
case .ignore:
29+
return .empty()
30+
case let .map(result):
31+
return .just(result)
32+
}
33+
}
3434
}
3535
}

Tests/RxSwift/filterMapTests.swift

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,20 @@ import RxSwift
1212
import RxSwiftExt
1313
import RxTest
1414

15-
enum FilterMapTestError: Error {
16-
case error
17-
}
15+
final class FilterMapTests: XCTestCase {
16+
private var scheduler: TestScheduler!
1817

19-
class FilterMapTests: XCTestCase {
20-
func testIgnoreEvenAndEvenizeOdds() {
18+
override func setUp() {
19+
super.setUp()
20+
scheduler = TestScheduler(initialClock: 0)
21+
}
22+
23+
override func tearDown() {
24+
scheduler = nil
25+
super.tearDown()
26+
}
2127

22-
let scheduler = TestScheduler(initialClock: 0)
28+
func testIgnoreEvenAndEvenizeOdds() {
2329
let observer = scheduler.createObserver(Int.self)
2430

2531
let values = 1..<10
@@ -39,7 +45,6 @@ class FilterMapTests: XCTestCase {
3945
}
4046

4147
func testErrorsWithSource() {
42-
let scheduler = TestScheduler(initialClock: 0)
4348
let observer = scheduler.createObserver(Int.self)
4449

4550
let subject = PublishSubject<Int>()
@@ -50,18 +55,49 @@ class FilterMapTests: XCTestCase {
5055
subject.on(.next(1))
5156
subject.on(.next(2))
5257
subject.on(.next(3))
53-
subject.on(.error(FilterMapTestError.error))
58+
subject.on(.error(testError))
5459

5560
scheduler.start()
5661

5762
let correct = Recorded.events([
5863
.next(0, 2),
5964
.next(0, 6),
60-
.error(0, FilterMapTestError.error)
65+
.error(0, testError)
6166
])
6267

6368
print(observer.events)
6469

6570
XCTAssertEqual(observer.events, correct)
6671
}
72+
73+
func testThrownError() {
74+
// Given
75+
let expectedErrored = 203
76+
let expectedEvents = Recorded.events([
77+
.next(201, 2),
78+
.error(expectedErrored, testError)
79+
])
80+
let source = scheduler.createHotObservable([
81+
.next(201, 1),
82+
.next(202, 2),
83+
.next(expectedErrored, 3), // should not fire due to error on 3
84+
.next(204, 4),
85+
.completed(205)
86+
])
87+
// When
88+
let result = scheduler.start {
89+
source.filterMap { element -> FilterMap<Int> in
90+
guard !element.isMultiple(of: 2) else {
91+
return .ignore
92+
}
93+
guard element != 3 else {
94+
throw testError
95+
}
96+
return .map(2 * element)
97+
}
98+
}
99+
// Then
100+
XCTAssertEqual(source.subscriptions, [Subscription(TestScheduler.Defaults.subscribed, expectedErrored)])
101+
XCTAssertEqual(result.events, expectedEvents)
102+
}
67103
}

Tests/TestErrors.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// TestErrors.swift
3+
// RxSwiftExt
4+
//
5+
// Created by Anton Nazarov on 25/05/2019.
6+
// Copyright © 2019 RxSwift Community. All rights reserved.
7+
//
8+
9+
enum TestError: Error {
10+
case dummyError
11+
}
12+
13+
let testError = TestError.dummyError

0 commit comments

Comments
 (0)