diff --git a/RxCocoa/Common/Observable+Bind.swift b/RxCocoa/Common/Observable+Bind.swift index 791844453..6ed41dc53 100644 --- a/RxCocoa/Common/Observable+Bind.swift +++ b/RxCocoa/Common/Observable+Bind.swift @@ -78,6 +78,86 @@ extension ObservableType { return self.map { $0 as E? }.bind(to: variable) } + /** + Creates new subscription and sends elements to publish relay. + + In case error occurs in debug mode, `fatalError` will be raised. + In case error occurs in release mode, `error` will be logged. + + - parameter to: Target publish relay for sequence elements. + - returns: Disposable object that can be used to unsubscribe the observer. + */ + public func bind(to relay: PublishRelay) -> Disposable { + return subscribe { e in + switch e { + case let .next(element): + relay.accept(element) + case let .error(error): + let error = "Binding error to publish relay: \(error)" + #if DEBUG + rxFatalError(error) + #else + print(error) + #endif + case .completed: + break + } + } + } + + /** + Creates new subscription and sends elements to publish relay. + + In case error occurs in debug mode, `fatalError` will be raised. + In case error occurs in release mode, `error` will be logged. + + - parameter to: Target publish relay for sequence elements. + - returns: Disposable object that can be used to unsubscribe the observer. + */ + public func bind(to relay: PublishRelay) -> Disposable { + return self.map { $0 as E? }.bind(to: relay) + } + + /** + Creates new subscription and sends elements to behavior relay. + + In case error occurs in debug mode, `fatalError` will be raised. + In case error occurs in release mode, `error` will be logged. + + - parameter to: Target behavior relay for sequence elements. + - returns: Disposable object that can be used to unsubscribe the observer. + */ + public func bind(to relay: BehaviorRelay) -> Disposable { + return subscribe { e in + switch e { + case let .next(element): + relay.accept(element) + case let .error(error): + let error = "Binding error to behavior relay: \(error)" + #if DEBUG + rxFatalError(error) + #else + print(error) + #endif + case .completed: + break + } + } + } + + /** + Creates new subscription and sends elements to behavior relay. + + In case error occurs in debug mode, `fatalError` will be raised. + In case error occurs in release mode, `error` will be logged. + + - parameter to: Target behavior relay for sequence elements. + - returns: Disposable object that can be used to unsubscribe the observer. + */ + public func bind(to relay: BehaviorRelay) -> Disposable { + return self.map { $0 as E? }.bind(to: relay) + } + /** Subscribes to observable sequence using custom binder function. diff --git a/Tests/RxCocoaTests/Observable+BindTests.swift b/Tests/RxCocoaTests/Observable+BindTests.swift index 442f824f2..da3ff9bbc 100644 --- a/Tests/RxCocoaTests/Observable+BindTests.swift +++ b/Tests/RxCocoaTests/Observable+BindTests.swift @@ -94,6 +94,86 @@ extension ObservableBindTest { } } +// MARK: bind(to:) publish relay + +extension ObservableBindTest { + func testBindToPublishRelay() { + var events: [Recorded>] = [] + + let relay = PublishRelay() + + _ = relay.subscribe{ event in + events.append(Recorded(time: 0, value: event)) + } + + _ = Observable.just(1).bind(to: relay) + + XCTAssertEqual(events, [ + next(1) + ]) + } + + func testBindToOptionalPublishRelay() { + var events: [Recorded>] = [] + + let relay = PublishRelay() + + _ = relay.subscribe{ event in + events.append(Recorded(time: 0, value: event)) + } + + _ = (Observable.just(1) as Observable).bind(to: relay) + + XCTAssertEqual(events, [ + next(1) + ]) + } + + func testBindToPublishRelayNoAmbiguity() { + var events: [Recorded>] = [] + + let relay = PublishRelay() + + _ = relay.subscribe{ event in + events.append(Recorded(time: 0, value: event)) + } + + _ = Observable.just(1).bind(to: relay) + + XCTAssertEqual(events, [ + next(1) + ]) + } +} + +// MARK: bind(to:) behavior relay + +extension ObservableBindTest { + func testBindToBehaviorRelay() { + let relay = BehaviorRelay(value: 0) + + _ = Observable.just(1).bind(to: relay) + + XCTAssertEqual(relay.value, 1) + } + + func testBindToOptionalBehaviorRelay() { + let relay = BehaviorRelay(value: 0) + + _ = (Observable.just(1) as Observable).bind(to: relay) + + XCTAssertEqual(relay.value, 1) + } + + func testBindToBehaviorRelayNoAmbiguity() { + let relay = BehaviorRelay(value: 0) + + _ = Observable.just(1).bind(to: relay) + + XCTAssertEqual(relay.value, 1) + } +} + // MARK: bind(to:) curried extension ObservableBindTest {