SingleEvent to Foundation.Result

This commit is contained in:
freak4pc 2020-09-19 21:20:14 +03:00 committed by Shai Mishali
parent d81524658e
commit 428f3c9624
7 changed files with 80 additions and 40 deletions

View File

@ -6,9 +6,7 @@
// Copyright © 2015 Krunoslav Zaher. All rights reserved. // Copyright © 2015 Krunoslav Zaher. All rights reserved.
// //
extension ObservableType { extension ObservableType {
/** /**
Converts an Observable into a Single that emits the whole sequence as a single array and then terminates. Converts an Observable into a Single that emits the whole sequence as a single array and then terminates.

View File

@ -6,6 +6,46 @@
// Copyright © 2020 Krunoslav Zaher. All rights reserved. // Copyright © 2020 Krunoslav Zaher. All rights reserved.
// //
// MARK: - Static allocation
extension InfallibleType {
/**
Returns an infallible sequence that contains a single element.
- seealso: [just operator on reactivex.io](http://reactivex.io/documentation/operators/just.html)
- parameter element: Single element in the resulting infallible sequence.
- returns: An infallible sequence containing the single specified element.
*/
public static func just(_ element: Element) -> Infallible<Element> {
Infallible(.just(element))
}
/**
Returns an infallible sequence that contains a single element.
- seealso: [just operator on reactivex.io](http://reactivex.io/documentation/operators/just.html)
- parameter element: Single element in the resulting infallible sequence.
- parameter scheduler: Scheduler to send the single element on.
- returns: An infallible sequence containing the single specified element.
*/
public static func just(_ element: Element, scheduler: ImmediateSchedulerType) -> Infallible<Element> {
Infallible(.just(element, scheduler: scheduler))
}
/**
Returns a non-terminating infallible sequence, which can be used to denote an infinite duration.
- seealso: [never operator on reactivex.io](http://reactivex.io/documentation/operators/empty-never-throw.html)
- returns: An infallible sequence whose observers will never get called.
*/
public static func never() -> Infallible<Element> {
Infallible(.never())
}
}
// MARK: - Filter // MARK: - Filter
extension InfallibleType { extension InfallibleType {
/** /**

View File

@ -14,14 +14,7 @@ import Foundation
public enum SingleTrait { } public enum SingleTrait { }
/// Represents a push style sequence containing 1 element. /// Represents a push style sequence containing 1 element.
public typealias Single<Element> = PrimitiveSequence<SingleTrait, Element> public typealias Single<Element> = PrimitiveSequence<SingleTrait, Element>
public typealias SingleEvent<Element> = Result<Element, Swift.Error>
public enum SingleEvent<Element> {
/// One and only sequence element is produced. (underlying observable sequence emits: `.next(Element)`, `.completed`)
case success(Element)
/// Sequence terminated with an error. (underlying observable sequence emits: `.error(Error)`)
case error(Swift.Error)
}
extension PrimitiveSequenceType where Trait == SingleTrait { extension PrimitiveSequenceType where Trait == SingleTrait {
public typealias SingleObserver = (SingleEvent<Element>) -> Void public typealias SingleObserver = (SingleEvent<Element>) -> Void
@ -41,7 +34,7 @@ extension PrimitiveSequenceType where Trait == SingleTrait {
case .success(let element): case .success(let element):
observer.on(.next(element)) observer.on(.next(element))
observer.on(.completed) observer.on(.completed)
case .error(let error): case .failure(let error):
observer.on(.error(error)) observer.on(.error(error))
} }
} }
@ -50,7 +43,6 @@ extension PrimitiveSequenceType where Trait == SingleTrait {
return PrimitiveSequence(raw: source) return PrimitiveSequence(raw: source)
} }
/** /**
Subscribes `observer` to receive events for this sequence. Subscribes `observer` to receive events for this sequence.
@ -66,24 +58,40 @@ extension PrimitiveSequenceType where Trait == SingleTrait {
case .next(let element): case .next(let element):
observer(.success(element)) observer(.success(element))
case .error(let error): case .error(let error):
observer(.error(error)) observer(.failure(error))
case .completed: case .completed:
rxFatalErrorInDebug("Singles can't emit a completion event") rxFatalErrorInDebug("Singles can't emit a completion event")
} }
} }
} }
/** /**
Subscribes a success handler, and an error handler for this sequence. Subscribes a success handler, and an error handler for this sequence.
- parameter onSuccess: Action to invoke for each element in the observable sequence. - parameter onSuccess: Action to invoke for each element in the observable sequence.
- parameter onError: Action to invoke upon errored termination of the observable sequence. - parameter onError: Action to invoke upon errored termination of the observable sequence.
- parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has - parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has
gracefully completed, errored, or if the generation is canceled by disposing subscription). gracefully completed, errored, or if the generation is canceled by disposing subscription).
- returns: Subscription object used to unsubscribe from the observable sequence. - returns: Subscription object used to unsubscribe from the observable sequence.
*/ */
@available(*, deprecated, renamed: "subscribe(onSuccess:onFailure:onDisposed:)")
public func subscribe(onSuccess: ((Element) -> Void)? = nil, public func subscribe(onSuccess: ((Element) -> Void)? = nil,
onError: ((Swift.Error) -> Void)? = nil, onError: ((Swift.Error) -> Void),
onDisposed: (() -> Void)? = nil) -> Disposable {
fatalError("This method has been renamed to subscribe(onSuccess:onFailure:onDisposed:)")
}
/**
Subscribes a success handler, and an error handler for this sequence.
- parameter onSuccess: Action to invoke for each element in the observable sequence.
- parameter onFailure: Action to invoke upon errored termination of the observable sequence.
- parameter onDisposed: Action to invoke upon any type of termination of sequence (if the sequence has
gracefully completed, errored, or if the generation is canceled by disposing subscription).
- returns: Subscription object used to unsubscribe from the observable sequence.
*/
public func subscribe(onSuccess: ((Element) -> Void)? = nil,
onFailure: ((Swift.Error) -> Void)? = nil,
onDisposed: (() -> Void)? = nil) -> Disposable { onDisposed: (() -> Void)? = nil) -> Disposable {
#if DEBUG #if DEBUG
let callStack = Hooks.recordCallStackOnError ? Thread.callStackSymbols : [] let callStack = Hooks.recordCallStackOnError ? Thread.callStackSymbols : []
@ -103,9 +111,9 @@ extension PrimitiveSequenceType where Trait == SingleTrait {
case .success(let element): case .success(let element):
onSuccess?(element) onSuccess?(element)
disposable.dispose() disposable.dispose()
case .error(let error): case .failure(let error):
if let onError = onError { if let onFailure = onFailure {
onError(error) onFailure(error)
} else { } else {
Hooks.defaultErrorHandler(callStack, error) Hooks.defaultErrorHandler(callStack, error)
} }

View File

@ -49,7 +49,7 @@ internal func equals<Element: Equatable>(lhs: Event<Element?>, rhs: Event<Elemen
internal func equals<Element: Equatable>(lhs: SingleEvent<Element>, rhs: SingleEvent<Element>) -> Bool { internal func equals<Element: Equatable>(lhs: SingleEvent<Element>, rhs: SingleEvent<Element>) -> Bool {
switch (lhs, rhs) { switch (lhs, rhs) {
case let (.error(e1), .error(e2)): case let (.failure(e1), .failure(e2)):
#if os(Linux) #if os(Linux)
return "\(e1)" == "\(e2)" return "\(e1)" == "\(e2)"
#else #else
@ -114,12 +114,6 @@ extension Event: Equatable where Element: Equatable {
} }
} }
extension SingleEvent: Equatable where Element: Equatable {
public static func == (lhs: SingleEvent<Element>, rhs: SingleEvent<Element>) -> Bool {
equals(lhs: lhs, rhs: rhs)
}
}
extension MaybeEvent: Equatable where Element: Equatable { extension MaybeEvent: Equatable where Element: Equatable {
public static func == (lhs: MaybeEvent<Element>, rhs: MaybeEvent<Element>) -> Bool { public static func == (lhs: MaybeEvent<Element>, rhs: MaybeEvent<Element>) -> Bool {
equals(lhs: lhs, rhs: rhs) equals(lhs: lhs, rhs: rhs)

View File

@ -47,8 +47,8 @@ public func XCTAssertEqual<Element: Equatable>(_ lhs: [Event<Element>], _ rhs: [
- parameter lhs: second set of events. - parameter lhs: second set of events.
*/ */
public func XCTAssertEqual<Element: Equatable>(_ lhs: [SingleEvent<Element>], _ rhs: [SingleEvent<Element>], file: StaticString = #file, line: UInt = #line) { public func XCTAssertEqual<Element: Equatable>(_ lhs: [SingleEvent<Element>], _ rhs: [SingleEvent<Element>], file: StaticString = #file, line: UInt = #line) {
let leftEquatable = lhs.map { AnyEquatable(target: $0, comparer: ==) } let leftEquatable = lhs.map { AnyEquatable(target: try! $0.get(), comparer: ==) }
let rightEquatable = rhs.map { AnyEquatable(target: $0, comparer: ==) } let rightEquatable = rhs.map { AnyEquatable(target: try! $0.get(), comparer: ==) }
#if os(Linux) #if os(Linux)
XCTAssertEqual(leftEquatable, rightEquatable) XCTAssertEqual(leftEquatable, rightEquatable)
#else #else
@ -58,7 +58,7 @@ public func XCTAssertEqual<Element: Equatable>(_ lhs: [SingleEvent<Element>], _
return return
} }
printSequenceDifferences(lhs, rhs, ==) printSequenceDifferences(lhs.map { try! $0.get() }, rhs.map { try! $0.get() }, ==)
} }
/** /**

View File

@ -133,8 +133,8 @@ extension ObservablePrimitiveSequenceTest {
_ = Single.just(1).subscribe(onSuccess: { element in _ = Single.just(1).subscribe(onSuccess: { element in
events.append(.success(element)) events.append(.success(element))
}, onError: { error in }, onFailure: { error in
events.append(.error(error)) events.append(.failure(error))
}) })
XCTAssertEqual(events, [.success(1)]) XCTAssertEqual(events, [.success(1)])
@ -145,11 +145,11 @@ extension ObservablePrimitiveSequenceTest {
_ = Single.error(testError).subscribe(onSuccess: { element in _ = Single.error(testError).subscribe(onSuccess: { element in
events.append(.success(element)) events.append(.success(element))
}, onError: { error in }, onFailure: { error in
events.append(.error(error)) events.append(.failure(error))
}) })
XCTAssertEqual(events, [.error(testError)]) XCTAssertEqual(events, [.failure(testError)])
} }
#if TRACE_RESOURCES #if TRACE_RESOURCES

View File

@ -37,7 +37,7 @@ extension SingleTest {
events.append(event) events.append(event)
} }
XCTAssertEqual(events, [.error(testError)]) XCTAssertEqual(events, [.failure(testError)])
} }
func testSingle_Subscription_onDisposed() { func testSingle_Subscription_onDisposed() {
@ -59,7 +59,7 @@ extension SingleTest {
subscription.dispose() subscription.dispose()
} }
scheduler.scheduleAt(203) { scheduler.scheduleAt(203) {
observer(.error(testError)) observer(.failure(testError))
} }
scheduler.start() scheduler.start()
// Then // Then
@ -105,7 +105,7 @@ extension SingleTest {
observer(.success(1)) observer(.success(1))
}) })
scheduler.scheduleAt(203, action: { scheduler.scheduleAt(203, action: {
observer(.error(testError)) observer(.failure(testError))
}) })
let res = scheduler.start { let res = scheduler.start {
@ -133,13 +133,13 @@ extension SingleTest {
var disposedTime: Int? var disposedTime: Int?
scheduler.scheduleAt(201, action: { scheduler.scheduleAt(201, action: {
observer(.error(testError)) observer(.failure(testError))
}) })
scheduler.scheduleAt(202, action: { scheduler.scheduleAt(202, action: {
observer(.success(1)) observer(.success(1))
}) })
scheduler.scheduleAt(203, action: { scheduler.scheduleAt(203, action: {
observer(.error(testError)) observer(.failure(testError))
}) })
let res = scheduler.start { let res = scheduler.start {
@ -183,7 +183,7 @@ extension SingleTest {
observer(.success(1)) observer(.success(1))
}) })
scheduler.scheduleAt(204, action: { scheduler.scheduleAt(204, action: {
observer(.error(testError)) observer(.failure(testError))
}) })
scheduler.start() scheduler.start()