Forked from danielt1263/ObservableEventTransforms.swift
Created
April 8, 2020 12:21
-
-
Save danipralea/0a1fd63135d95f89cd51d555f08b735e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ObservableEventTransforms.swift | |
// | |
// Created by Daniel Tartaglia on 9/22/18. | |
// Copyright © 2019 Daniel Tartaglia. MIT License. | |
// | |
import RxSwift | |
/** | |
All of the methods below assume that you have an `Observable<Event<Input>>` and want to transform it into an | |
`Observable<Event<Output>>` through some means. | |
*/ | |
extension ObservableType { | |
/// - parameter transform: `(Input) -> Output` | |
public func mapEvent<Input, Output>( _ transform: @escaping (Input) throws -> Output) -> Observable<Event<Output>> where Element == Event<Input> { | |
return map { $0.map(transform) } | |
} | |
/// - parameter transform: `(Input) -> Event<Output>` | |
public func mapEvent<Input, Output>( _ transform: @escaping (Input) throws -> Event<Output>) -> Observable<Event<Output>> where Element == Event<Input> { | |
return map { $0.flatMap(transform) } | |
} | |
/// - parameter transform: `(Input) -> Observable<Output>`. | |
public func flatMapEvent<Input, Output>(_ transform: @escaping (Input) throws -> Observable<Output>) -> Observable<Event<Output>> where Element == Event<Input> { | |
return flatMapEvent { try embedResult($0, transform) } | |
} | |
/// - parameter transform: `(Input) -> Observable<Output>`. | |
public func flatMapLatestEvent<Input, Output>(_ transform: @escaping (Input) throws -> Observable<Output>) -> Observable<Event<Output>> where Element == Event<Input> { | |
return flatMapLatestEvent { try embedResult($0, transform) } | |
} | |
/// - parameter transform: `(Input) -> Observable<Output>`. | |
public func flatMapFirstEvent<Input, Output>(_ transform: @escaping (Input) throws -> Observable<Output>) -> Observable<Event<Output>> where Element == Event<Input> { | |
return flatMapFirstEvent { try embedResult($0, transform) } | |
} | |
/// - parameter transform: `(Input) -> Observable<Output>`. | |
public func concatMapEvent<Input, Output>(_ transform: @escaping (Input) throws -> Observable<Output>) -> Observable<Event<Output>> where Element == Event<Input> { | |
return concatMapEvent { try embedResult($0, transform) } | |
} | |
/// - parameter transform: `(Input) -> Observable<Event<Output>>`. | |
public func flatMapEvent<Input, Output>(_ transform: @escaping (Input) throws -> Observable<Event<Output>>) -> Observable<Event<Output>> where Element == Event<Input> { | |
return flatMap { $0.embedIntoObservable(transform) } | |
} | |
/// - parameter transform: `(Input) -> Observable<Event<Output>>`. | |
public func flatMapLatestEvent<Input, Output>(_ transform: @escaping (Input) throws -> Observable<Event<Output>>) -> Observable<Event<Output>> where Element == Event<Input> { | |
return flatMapLatest { $0.embedIntoObservable(transform) } | |
} | |
/// - parameter transform: `(Input) -> Observable<Event<Output>>`. | |
public func flatMapFirstEvent<Input, Output>(_ transform: @escaping (Input) throws -> Observable<Event<Output>>) -> Observable<Event<Output>> where Element == Event<Input> { | |
return flatMapFirst { $0.embedIntoObservable(transform) } | |
} | |
/// - parameter transform: `(Input) -> Observable<Event<Output>>`. | |
public func concatMapEvent<Input, Output>(_ transform: @escaping (Input) throws -> Observable<Event<Output>>) -> Observable<Event<Output>> where Element == Event<Input> { | |
return concatMap { $0.embedIntoObservable(transform) } | |
} | |
} | |
extension ObservableType { | |
/** | |
Allows you to filter an Observable<Event<T>> based on a predicate that takes a T. | |
- parameter pred: `(Input) -> Bool`. | |
*/ | |
public func filterEvent<Input>(includeErrors: Bool = true, _ pred: @escaping (Input) throws -> Bool) -> Observable<Event<Input>> where Element == Event<Input> { | |
return filter { value in | |
switch value { | |
case let .next(input): | |
do { | |
return try pred(input) | |
} | |
catch { | |
return includeErrors | |
} | |
case .error: | |
return includeErrors | |
case .completed: | |
return true | |
} | |
} | |
} | |
} | |
extension Event { | |
public func flatMap<T>(_ transform: (Element) throws -> Event<T>) -> Event<T> { | |
switch self { | |
case let .next(element): | |
do { | |
return try transform(element) | |
} | |
catch { | |
return .error(error) | |
} | |
case let .error(error): | |
return .error(error) | |
case .completed: | |
return .completed | |
} | |
} | |
fileprivate func embedIntoObservable<Output>(_ transform: @escaping (Element) throws -> Observable<Event<Output>>) -> Observable<Event<Output>> { | |
switch self { | |
case let .next(input): | |
do { | |
return try transform(input) | |
.catchError { Observable<Event<Output>>.just(.error($0)) } | |
} | |
catch { | |
return .just(.error(error)) | |
} | |
case let .error(error): | |
return .just(.error(error)) | |
case .completed: | |
return .just(.completed) | |
} | |
} | |
} | |
private | |
func embedResult<Input, Output>(_ input: Input, _ transform: @escaping (Input) throws -> Observable<Output>) throws -> Observable<Event<Output>> { | |
return try transform(input).map(Event<Output>.next) | |
.catchError { Observable<Event<Output>>.just(.error($0)) } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment