from typing import Callable, List, TypeVar from reactivex import Observable from reactivex import operators as ops from reactivex.typing import Predicate, PredicateIndexed _T = TypeVar("_T") def partition_( predicate: Predicate[_T], ) -> Callable[[Observable[_T]], List[Observable[_T]]]: def partition(source: Observable[_T]) -> List[Observable[_T]]: """The partially applied `partition` operator. Returns two observables which partition the observations of the source by the given function. The first will trigger observations for those values for which the predicate returns true. The second will trigger observations for those values where the predicate returns false. The predicate is executed once for each subscribed observer. Both also propagate all error observations arising from the source and each completes when the source completes. Args: source: Source obserable to partition. Returns: A list of observables. The first triggers when the predicate returns True, and the second triggers when the predicate returns False. """ def not_predicate(x: _T) -> bool: return not predicate(x) published = source.pipe( ops.publish(), ops.ref_count(), ) return [ published.pipe(ops.filter(predicate)), published.pipe(ops.filter(not_predicate)), ] return partition def partition_indexed_( predicate_indexed: PredicateIndexed[_T], ) -> Callable[[Observable[_T]], List[Observable[_T]]]: def partition_indexed(source: Observable[_T]) -> List[Observable[_T]]: """The partially applied indexed partition operator. Returns two observables which partition the observations of the source by the given function. The first will trigger observations for those values for which the predicate returns true. The second will trigger observations for those values where the predicate returns false. The predicate is executed once for each subscribed observer. Both also propagate all error observations arising from the source and each completes when the source completes. Args: source: Source observable to partition. Returns: A list of observables. The first triggers when the predicate returns True, and the second triggers when the predicate returns False. """ def not_predicate_indexed(x: _T, i: int) -> bool: return not predicate_indexed(x, i) published = source.pipe( ops.publish(), ops.ref_count(), ) return [ published.pipe(ops.filter_indexed(predicate_indexed)), published.pipe(ops.filter_indexed(not_predicate_indexed)), ] return partition_indexed __all__ = ["partition_", "partition_indexed_"]