*/ private $coroutine; /** * @param callable(callable(TValue):Promise):\Generator $callable * * @throws \Error Thrown if the callable does not return a Generator. */ public function __construct(callable $callable) { $source = new class implements Internal\GeneratorStream { use Internal\Yielder { generate as public; } }; if (\PHP_VERSION_ID < 70100) { $yield = static function ($value) use ($source): Promise { return $source->yield($value); }; } else { $yield = \Closure::fromCallable([$source, "yield"]); } $result = $callable($yield); if (!$result instanceof \Generator) { throw new \TypeError("The callable did not return a Generator"); } $this->coroutine = new Coroutine($result); $this->coroutine->onResolve(static function ($exception) use ($source) { if ($exception) { $source->fail($exception); return; } $source->complete(); }); $this->generator = $source->generate(); } /** * Continues the async generator, resolving the back-pressure promise with null. * * @return Promise */ public function continue(): Promise { return $this->generator->continue(); } /** * Sends a value to the async generator, resolving the back-pressure promise with the given value. * * @param mixed $value Value to send to the async generator. * * @psalm-param TSend $value * * @return Promise */ public function send($value): Promise { return $this->generator->send($value); } /** * Throws an exception into the async generator, failing the back-pressure promise with the given exception. * * @param \Throwable $exception Exception to throw into the async generator. * * @return Promise */ public function throw(\Throwable $exception): Promise { return $this->generator->throw($exception); } /** * @return Promise */ public function getReturn(): Promise { return $this->coroutine; } }