Skip to content

Commit ec7e952

Browse files
Merge first and firstOrError operators.
The new operator returns an optional value.
1 parent d4a3020 commit ec7e952

File tree

4 files changed

+21
-177
lines changed

4 files changed

+21
-177
lines changed

RxSwift/Observables/First.swift

+11-25
Original file line numberDiff line numberDiff line change
@@ -6,50 +6,36 @@
66
// Copyright © 2017 Krunoslav Zaher. All rights reserved.
77
//
88

9-
fileprivate final class FirstSink<O: ObserverType> : Sink<O>, ObserverType {
10-
typealias ElementType = O.E
11-
typealias Parent = First<ElementType>
12-
typealias E = ElementType
13-
14-
private var _parent: Parent
15-
16-
init(parent: Parent, observer: O, cancel: Cancelable) {
17-
_parent = parent
18-
super.init(observer: observer, cancel: cancel)
19-
}
9+
fileprivate final class FirstSink<Element, O: ObserverType> : Sink<O>, ObserverType where O.E == Element? {
10+
typealias E = Element
11+
typealias Parent = First<E>
2012

2113
func on(_ event: Event<E>) {
2214
switch event {
2315
case .next(let value):
2416
forwardOn(.next(value))
2517
forwardOn(.completed)
2618
dispose()
27-
case .error:
28-
forwardOn(event)
19+
case .error(let error):
20+
forwardOn(.error(error))
2921
dispose()
3022
case .completed:
31-
if let defaultElement = _parent._defaultItem {
32-
forwardOn(.next(defaultElement))
33-
forwardOn(.completed)
34-
} else {
35-
forwardOn(.error(RxError.noElements))
36-
}
23+
forwardOn(.next(nil))
24+
forwardOn(.completed)
3725
dispose()
3826
}
3927
}
4028
}
4129

42-
final class First<Element>: Producer<Element> {
30+
final class First<Element>: Producer<Element?> {
4331
fileprivate let _source: Observable<Element>
44-
fileprivate let _defaultItem: E?
4532

46-
init(source: Observable<Element>, defaultItem: E? = nil) {
33+
init(source: Observable<Element>) {
4734
_source = source
48-
_defaultItem = defaultItem
4935
}
5036

51-
override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
52-
let sink = FirstSink(parent: self, observer: observer, cancel: cancel)
37+
override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element? {
38+
let sink = FirstSink(observer: observer, cancel: cancel)
5339
let subscription = _source.subscribe(sink)
5440
return (sink: sink, subscription: subscription)
5541
}

RxSwift/Traits/PrimitiveSequence.swift

+3-16
Original file line numberDiff line numberDiff line change
@@ -774,26 +774,13 @@ extension ObservableType {
774774

775775
/**
776776
The `first` operator emits only the very first item emitted by this Observable,
777-
or a default item if this Observable completes without emitting anything.
777+
or nil if this Observable completes without emitting anything.
778778

779779
- seealso: [single operator on reactivex.io](http://reactivex.io/documentation/operators/first.html)
780780

781-
- parameter defaultItem: the default item to emit if the source doesn't emit anything
782-
- returns: An observable sequence that emits a single element or a default item if the source Publisher completes without emitting any items.
781+
- returns: An observable sequence that emits a single element or nil if the source Publisher completes without emitting any items.
783782
*/
784-
public func first(_ defaultItem: E) -> Single<E> {
785-
return PrimitiveSequence(raw: First(source: self.asObservable(), defaultItem: defaultItem))
786-
}
787-
788-
/**
789-
The `firstOrError` operator emits only the very first item emitted by this Observable or
790-
throws a `RxError.noElements` if this Observable is empty.
791-
792-
- seealso: [single operator on reactivex.io](http://reactivex.io/documentation/operators/first.html)
793-
794-
- returns: An observable sequence that emits a single element or a default item if the source Publisher completes without emitting any items.
795-
*/
796-
public func firstOrError() -> Single<E> {
783+
public func first() -> Single<E?> {
797784
return PrimitiveSequence(raw: First(source: self.asObservable()))
798785
}
799786

Sources/AllTestz/main.swift

-5
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,6 @@ final class PrimitiveSequenceTest_ : PrimitiveSequenceTest, RxTestCase {
159159
("testFirst_Many", PrimitiveSequenceTest.testFirst_Many),
160160
("testFirst_ManyWithoutCompletion", PrimitiveSequenceTest.testFirst_ManyWithoutCompletion),
161161
("testFirst_Error", PrimitiveSequenceTest.testFirst_Error),
162-
("testFirstOrError_Empty", PrimitiveSequenceTest.testFirstOrError_Empty),
163-
("testFirstOrError_One", PrimitiveSequenceTest.testFirstOrError_One),
164-
("testFirstOrError_Many", PrimitiveSequenceTest.testFirstOrError_Many),
165-
("testFirstOrError_ManyWithoutCompletion", PrimitiveSequenceTest.testFirstOrError_ManyWithoutCompletion),
166-
("testFirstOrError_Error", PrimitiveSequenceTest.testFirstOrError_Error),
167162
("testAsMaybe_Empty", PrimitiveSequenceTest.testAsMaybe_Empty),
168163
("testAsMaybe_One", PrimitiveSequenceTest.testAsMaybe_One),
169164
("testAsMaybe_Many", PrimitiveSequenceTest.testAsMaybe_Many),

Tests/RxSwiftTests/PrimitiveSequenceTest.swift

+7-131
Original file line numberDiff line numberDiff line change
@@ -1055,13 +1055,13 @@ extension PrimitiveSequenceTest {
10551055
error(260, testError)
10561056
])
10571057

1058-
let res = scheduler.start { () -> Observable<Int> in
1059-
let single: Single<Int> = xs.first(0)
1058+
let res: TestableObserver<Int> = scheduler.start { () -> Observable<Int> in
1059+
let single: Single<Int> = xs.first().map { $0 ?? -1 }
10601060
return single.asObservable()
10611061
}
10621062

10631063
XCTAssertEqual(res.events, [
1064-
next(250, 0),
1064+
next(250, -1),
10651065
completed(250)
10661066
])
10671067

@@ -1081,7 +1081,7 @@ extension PrimitiveSequenceTest {
10811081
])
10821082

10831083
let res = scheduler.start { () -> Observable<Int> in
1084-
let single: Single<Int> = xs.first(0)
1084+
let single: Single<Int> = xs.first().map { $0 ?? -1 }
10851085
return single.asObservable()
10861086
}
10871087

@@ -1107,7 +1107,7 @@ extension PrimitiveSequenceTest {
11071107
])
11081108

11091109
let res = scheduler.start { () -> Observable<Int> in
1110-
let single: Single<Int> = xs.first(0)
1110+
let single: Single<Int> = xs.first().map { $0 ?? -1 }
11111111
return single.asObservable()
11121112
}
11131113

@@ -1133,7 +1133,7 @@ extension PrimitiveSequenceTest {
11331133
])
11341134

11351135
let res = scheduler.start { () -> Observable<Int> in
1136-
let single: Single<Int> = xs.first(0)
1136+
let single: Single<Int> = xs.first().map { $0 ?? -1 }
11371137
return single.asObservable()
11381138
}
11391139

@@ -1156,131 +1156,7 @@ extension PrimitiveSequenceTest {
11561156
])
11571157

11581158
let res = scheduler.start { () -> Observable<Int> in
1159-
let single: Single<Int> = xs.first(0)
1160-
return single.asObservable()
1161-
}
1162-
1163-
XCTAssertEqual(res.events, [
1164-
error(210, testError)
1165-
])
1166-
1167-
XCTAssertEqual(xs.subscriptions, [
1168-
Subscription(200, 210)
1169-
])
1170-
}
1171-
}
1172-
1173-
extension PrimitiveSequenceTest {
1174-
func testFirstOrError_Empty() {
1175-
let scheduler = TestScheduler(initialClock: 0)
1176-
1177-
let xs = scheduler.createHotObservable([
1178-
next(150, 1),
1179-
completed(250),
1180-
error(260, testError)
1181-
])
1182-
1183-
let res = scheduler.start { () -> Observable<Int> in
1184-
let single: Single<Int> = xs.firstOrError()
1185-
return single.asObservable()
1186-
}
1187-
1188-
XCTAssertEqual(res.events, [
1189-
error(250, RxError.noElements)
1190-
])
1191-
1192-
XCTAssertEqual(xs.subscriptions, [
1193-
Subscription(200, 250)
1194-
])
1195-
}
1196-
1197-
func testFirstOrError_One() {
1198-
let scheduler = TestScheduler(initialClock: 0)
1199-
1200-
let xs = scheduler.createHotObservable([
1201-
next(150, 1),
1202-
next(210, 2),
1203-
completed(250),
1204-
error(260, testError)
1205-
])
1206-
1207-
let res = scheduler.start { () -> Observable<Int> in
1208-
let single: Single<Int> = xs.firstOrError()
1209-
return single.asObservable()
1210-
}
1211-
1212-
XCTAssertEqual(res.events, [
1213-
next(210, 2),
1214-
completed(210)
1215-
])
1216-
1217-
XCTAssertEqual(xs.subscriptions, [
1218-
Subscription(200, 210)
1219-
])
1220-
}
1221-
1222-
func testFirstOrError_Many() {
1223-
let scheduler = TestScheduler(initialClock: 0)
1224-
1225-
let xs = scheduler.createHotObservable([
1226-
next(150, 1),
1227-
next(210, 2),
1228-
next(220, 3),
1229-
completed(250),
1230-
error(260, testError)
1231-
])
1232-
1233-
let res = scheduler.start { () -> Observable<Int> in
1234-
let single: Single<Int> = xs.firstOrError()
1235-
return single.asObservable()
1236-
}
1237-
1238-
XCTAssertEqual(res.events, [
1239-
next(210, 2),
1240-
completed(210)
1241-
])
1242-
1243-
XCTAssertEqual(xs.subscriptions, [
1244-
Subscription(200, 210)
1245-
])
1246-
}
1247-
1248-
func testFirstOrError_ManyWithoutCompletion() {
1249-
let scheduler = TestScheduler(initialClock: 0)
1250-
1251-
let xs = scheduler.createHotObservable([
1252-
next(150, 1),
1253-
next(160, 2),
1254-
next(280, 3),
1255-
next(250, 4),
1256-
next(300, 5)
1257-
])
1258-
1259-
let res = scheduler.start { () -> Observable<Int> in
1260-
let single: Single<Int> = xs.firstOrError()
1261-
return single.asObservable()
1262-
}
1263-
1264-
XCTAssertEqual(res.events, [
1265-
next(250, 4),
1266-
completed(250)
1267-
])
1268-
1269-
XCTAssertEqual(xs.subscriptions, [
1270-
Subscription(200, 250)
1271-
])
1272-
}
1273-
1274-
func testFirstOrError_Error() {
1275-
let scheduler = TestScheduler(initialClock: 0)
1276-
1277-
let xs = scheduler.createHotObservable([
1278-
next(150, 1),
1279-
error(210, testError)
1280-
])
1281-
1282-
let res = scheduler.start { () -> Observable<Int> in
1283-
let single: Single<Int> = xs.firstOrError()
1159+
let single: Single<Int> = xs.first().map { $0 ?? -1 }
12841160
return single.asObservable()
12851161
}
12861162

0 commit comments

Comments
 (0)