You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.1 KiB

5 years ago
  1. //
  2. // flatMapSync.swift
  3. // RxSwiftExt
  4. //
  5. // Created by Jeremie Girault on 31/05/2017.
  6. // Copyright © 2017 RxSwift Community. All rights reserved.
  7. //
  8. import RxSwift
  9. /**
  10. Defines a synchronous custom operator output in the form of a Type
  11. */
  12. public protocol CustomOperator {
  13. associatedtype Result
  14. /**
  15. Applies the operator instance output to a sink (eventually the observer)
  16. The sink is non-escaping for performance and safety reasons.
  17. */
  18. func apply(_ sink: (Result) -> Void)
  19. }
  20. /**
  21. A type-erased CustomOperator
  22. */
  23. public struct AnyOperator<Result>: CustomOperator {
  24. /** The output sink type of this synchronous operator */
  25. public typealias Sink = (Result) -> Void
  26. private let _apply: (Sink) -> Void
  27. public init(_ apply: @escaping (Sink) -> Void) { self._apply = apply }
  28. // CustomOperator implementation
  29. public func apply(_ sink: Sink) { _apply(sink) }
  30. }
  31. extension CustomOperator {
  32. /** Filters values out from the output of the Observable */
  33. public static var filter: AnyOperator<Result> {
  34. return AnyOperator { _ in }
  35. }
  36. /** Replaces values in the output of the Observable */
  37. public static func map(_ values: Result...) -> AnyOperator<Result> {
  38. return AnyOperator { sink in values.forEach { sink($0) } }
  39. }
  40. }
  41. extension ObservableType {
  42. /**
  43. FlatMaps values from a stream synchronously using CustomOperator type.
  44. - The returned Observable will error and complete with the source.
  45. - `next` values will be transformed by according to the CustomOperator application rules.
  46. see filterMap for an example of a custom operator
  47. */
  48. public func flatMapSync<O: CustomOperator>(_ transform: @escaping (E) -> O) -> Observable<O.Result> {
  49. return Observable.create { observer in
  50. return self.subscribe { event in
  51. switch event {
  52. case .next(let element): transform(element).apply { observer.onNext($0) }
  53. case .completed: observer.onCompleted()
  54. case .error(let error): observer.onError(error)
  55. }
  56. }
  57. }
  58. }
  59. }