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

//
// flatMapSync.swift
// RxSwiftExt
//
// Created by Jeremie Girault on 31/05/2017.
// Copyright © 2017 RxSwift Community. All rights reserved.
//
import RxSwift
/**
Defines a synchronous custom operator output in the form of a Type
*/
public protocol CustomOperator {
associatedtype Result
/**
Applies the operator instance output to a sink (eventually the observer)
The sink is non-escaping for performance and safety reasons.
*/
func apply(_ sink: (Result) -> Void)
}
/**
A type-erased CustomOperator
*/
public struct AnyOperator<Result>: CustomOperator {
/** The output sink type of this synchronous operator */
public typealias Sink = (Result) -> Void
private let _apply: (Sink) -> Void
public init(_ apply: @escaping (Sink) -> Void) { self._apply = apply }
// CustomOperator implementation
public func apply(_ sink: Sink) { _apply(sink) }
}
extension CustomOperator {
/** Filters values out from the output of the Observable */
public static var filter: AnyOperator<Result> {
return AnyOperator { _ in }
}
/** Replaces values in the output of the Observable */
public static func map(_ values: Result...) -> AnyOperator<Result> {
return AnyOperator { sink in values.forEach { sink($0) } }
}
}
extension ObservableType {
/**
FlatMaps values from a stream synchronously using CustomOperator type.
- The returned Observable will error and complete with the source.
- `next` values will be transformed by according to the CustomOperator application rules.
see filterMap for an example of a custom operator
*/
public func flatMapSync<O: CustomOperator>(_ transform: @escaping (E) -> O) -> Observable<O.Result> {
return Observable.create { observer in
return self.subscribe { event in
switch event {
case .next(let element): transform(element).apply { observer.onNext($0) }
case .completed: observer.onCompleted()
case .error(let error): observer.onError(error)
}
}
}
}
}