implements decorators pipeline

This commit is contained in:
Fabio Ivona
2021-10-08 15:29:35 +02:00
parent d802e88148
commit e92d9bfaae
5 changed files with 202 additions and 10 deletions

View File

@ -30,4 +30,9 @@ final class Extendable
{
$this->extendableClass::extend($name, $extend);
}
public function decorate(string $name, Closure $extend): void
{
$this->extendableClass::decorate($name, $extend);
}
}

69
src/Support/Pipeline.php Normal file
View File

@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
namespace Pest\Support;
use Closure;
final class Pipeline
{
/** @var array<Closure> */
private $pipes = [];
/** @var array<mixed> */
private $passable;
/**
* @param array<mixed> $passable
*/
public function __construct(...$passable)
{
$this->passable = $passable;
}
/**
* @param array<mixed> $passable
*/
public static function send(...$passable): self
{
return new self(...$passable);
}
/**
* @param array<Closure> $pipes
*/
public function through(array $pipes): self
{
$this->pipes = $pipes;
return $this;
}
public function finally(Closure $finalClosure): void
{
$pipeline = array_reduce(
array_reverse($this->pipes),
$this->carry(),
$this->prepareFinalClosure($finalClosure)
);
$pipeline(...$this->passable);
}
public function carry(): Closure
{
return function ($stack, $pipe): Closure {
return function (...$passable) use ($stack, $pipe) {
return $pipe($stack, ...$passable);
};
};
}
private function prepareFinalClosure(Closure $finalClosure): Closure
{
return function (...$passable) use ($finalClosure) {
return $finalClosure($passable);
};
}
}