132 lines
4.2 KiB
Python
132 lines
4.2 KiB
Python
from asyncio import Future
|
|
from typing import Any, Callable, Optional, TypeVar, Union, cast
|
|
|
|
from reactivex import Observable, from_, from_future
|
|
from reactivex import operators as ops
|
|
from reactivex.internal.basic import identity
|
|
from reactivex.typing import Mapper, MapperIndexed
|
|
|
|
_T1 = TypeVar("_T1")
|
|
_T2 = TypeVar("_T2")
|
|
|
|
|
|
def _flat_map_internal(
|
|
source: Observable[_T1],
|
|
mapper: Optional[Mapper[_T1, Any]] = None,
|
|
mapper_indexed: Optional[MapperIndexed[_T1, Any]] = None,
|
|
) -> Observable[Any]:
|
|
def projection(x: _T1, i: int) -> Observable[Any]:
|
|
mapper_result: Any = (
|
|
mapper(x)
|
|
if mapper
|
|
else mapper_indexed(x, i)
|
|
if mapper_indexed
|
|
else identity
|
|
)
|
|
if isinstance(mapper_result, Future):
|
|
result: Observable[Any] = from_future(cast("Future[Any]", mapper_result))
|
|
elif isinstance(mapper_result, Observable):
|
|
result = mapper_result
|
|
else:
|
|
result = from_(mapper_result)
|
|
return result
|
|
|
|
return source.pipe(
|
|
ops.map_indexed(projection),
|
|
ops.merge_all(),
|
|
)
|
|
|
|
|
|
def flat_map_(
|
|
mapper: Optional[Mapper[_T1, Observable[_T2]]] = None
|
|
) -> Callable[[Observable[_T1]], Observable[_T2]]:
|
|
def flat_map(source: Observable[_T1]) -> Observable[_T2]:
|
|
"""One of the Following:
|
|
Projects each element of an observable sequence to an observable
|
|
sequence and merges the resulting observable sequences into one
|
|
observable sequence.
|
|
|
|
Example:
|
|
>>> flat_map(source)
|
|
|
|
Args:
|
|
source: Source observable to flat map.
|
|
|
|
Returns:
|
|
An operator function that takes a source observable and returns
|
|
an observable sequence whose elements are the result of invoking
|
|
the one-to-many transform function on each element of the
|
|
input sequence .
|
|
"""
|
|
|
|
if callable(mapper):
|
|
ret = _flat_map_internal(source, mapper=mapper)
|
|
else:
|
|
ret = _flat_map_internal(source, mapper=lambda _: mapper)
|
|
|
|
return ret
|
|
|
|
return flat_map
|
|
|
|
|
|
def flat_map_indexed_(
|
|
mapper_indexed: Optional[Any] = None,
|
|
) -> Callable[[Observable[Any]], Observable[Any]]:
|
|
def flat_map_indexed(source: Observable[Any]) -> Observable[Any]:
|
|
"""One of the Following:
|
|
Projects each element of an observable sequence to an observable
|
|
sequence and merges the resulting observable sequences into one
|
|
observable sequence.
|
|
|
|
Example:
|
|
>>> flat_map_indexed(source)
|
|
|
|
Args:
|
|
source: Source observable to flat map.
|
|
|
|
Returns:
|
|
An observable sequence whose elements are the result of invoking
|
|
the one-to-many transform function on each element of the input
|
|
sequence.
|
|
"""
|
|
|
|
if callable(mapper_indexed):
|
|
ret = _flat_map_internal(source, mapper_indexed=mapper_indexed)
|
|
else:
|
|
ret = _flat_map_internal(source, mapper=lambda _: mapper_indexed)
|
|
return ret
|
|
|
|
return flat_map_indexed
|
|
|
|
|
|
def flat_map_latest_(
|
|
mapper: Mapper[_T1, Union[Observable[_T2], "Future[_T2]"]]
|
|
) -> Callable[[Observable[_T1]], Observable[_T2]]:
|
|
def flat_map_latest(source: Observable[_T1]) -> Observable[_T2]:
|
|
"""Projects each element of an observable sequence into a new
|
|
sequence of observable sequences by incorporating the element's
|
|
index and then transforms an observable sequence of observable
|
|
sequences into an observable sequence producing values only
|
|
from the most recent observable sequence.
|
|
|
|
Args:
|
|
source: Source observable to flat map latest.
|
|
|
|
Returns:
|
|
An observable sequence whose elements are the result of
|
|
invoking the transform function on each element of source
|
|
producing an observable of Observable sequences and that at
|
|
any point in time produces the elements of the most recent
|
|
inner observable sequence that has been received.
|
|
"""
|
|
|
|
return source.pipe(
|
|
ops.map(mapper),
|
|
ops.switch_latest(),
|
|
)
|
|
|
|
return flat_map_latest
|
|
|
|
|
|
__all__ = ["flat_map_", "flat_map_latest_", "flat_map_indexed_"]
|