Files
onepilot/frogpilot/third_party/reactivex/operators/_scan.py
T
firestar5683 d0e1db6766 StarPilot
2026-03-22 03:15:05 -05:00

61 lines
1.7 KiB
Python

from typing import Callable, Type, TypeVar, Union, cast
from reactivex import Observable, abc, defer
from reactivex import operators as ops
from reactivex.internal.utils import NotSet
from reactivex.typing import Accumulator
_T = TypeVar("_T")
_TState = TypeVar("_TState")
def scan_(
accumulator: Accumulator[_TState, _T], seed: Union[_TState, Type[NotSet]] = NotSet
) -> Callable[[Observable[_T]], Observable[_TState]]:
has_seed = seed is not NotSet
def scan(source: Observable[_T]) -> Observable[_TState]:
"""Partially applied scan operator.
Applies an accumulator function over an observable sequence and
returns each intermediate result.
Examples:
>>> scanned = scan(source)
Args:
source: The observable source to scan.
Returns:
An observable sequence containing the accumulated values.
"""
def factory(scheduler: abc.SchedulerBase) -> Observable[_TState]:
has_accumulation = False
accumulation: _TState = cast(_TState, None)
def projection(x: _T) -> _TState:
nonlocal has_accumulation
nonlocal accumulation
if has_accumulation:
accumulation = accumulator(accumulation, x)
else:
accumulation = (
accumulator(cast(_TState, seed), x)
if has_seed
else cast(_TState, x)
)
has_accumulation = True
return accumulation
return source.pipe(ops.map(projection))
return defer(factory)
return scan
__all__ = ["scan_"]