# Copyright (c) PARRRATE T&V 2021. All rights reserved. from typing import Optional from bu4.evaluation.av.aftervalue import AfterValue from bu4.evaluation.constructs.evaluable import Evaluable from bu4.evaluation.constructs.evalue import EValue from bu4.evaluation.targets.avanonymouscontainer import AVAnonymousContainer from bu4.evaluation.targets.avcall import AVCall from bu4.evaluation.targets.avtarget import AVTarget __all__ = ('EAsync',) class EAsync(EValue): def __init__(self): self.__anext: Optional[Evaluable] = None def call(self, argument: Evaluable) -> Evaluable: return AfterAsync(self, AVCall(argument)) async def _anext(self) -> Evaluable: raise NotImplementedError async def anext(self) -> Evaluable: if self.__anext is None: self.__anext = AVAnonymousContainer(await self._anext()) return self.__anext class AfterAsync(EAsync): easync: EAsync target: AVTarget def __init__(self, easync: EAsync, target: AVTarget): self.easync = easync self.target = target super().__init__() async def _anext(self) -> Evaluable: if isinstance(self.easync, AfterAsync): return AfterAsync(self.easync.easync, AAChain(self.easync, self.easync.target)) return AfterValue(await self.easync.anext(), self.target) class AAChain(AVTarget): def __init__(self, evaluable: AfterAsync, target: AVTarget): if isinstance(evaluable.target, AAChain): raise TypeError self.evaluable = evaluable self.target = target def given(self, value: EValue) -> Evaluable: return AfterValue(self.evaluable.target.given(value), self.target)