Passed
Push — main ( fcce5c...1de410 )
by Chema
01:27
created

MiddlewarePipeline::handle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
dl 0
loc 14
rs 10
c 1
b 0
f 0
eloc 5
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Router\Middleware;
6
7
use Closure;
8
use Gacela\Container\Container;
9
use Gacela\Router\Entities\Request;
10
11
use function is_string;
12
13
final class MiddlewarePipeline
14
{
15
    /**
16
     * @param list<MiddlewareInterface|class-string<MiddlewareInterface>> $middlewares
17
     */
18
    public function __construct(
19
        private readonly array $middlewares = [],
20
    ) {
21
    }
22
23
    public function handle(Request $request, Closure $finalHandler): string
24
    {
25
        /**
26
         * @psalm-suppress MixedArgumentTypeCoercion
27
         *
28
         * @var Closure(Request): string $pipeline
29
         */
30
        $pipeline = array_reduce(
31
            array_reverse($this->middlewares),
32
            $this->carry(),
33
            $finalHandler,
34
        );
35
36
        return $pipeline($request);
37
    }
38
39
    private function carry(): Closure
40
    {
41
        return static function (Closure $next, MiddlewareInterface|string $middleware): Closure {
42
            return static function (Request $request) use ($next, $middleware): string {
43
                if (is_string($middleware)) {
44
                    /** @var class-string<MiddlewareInterface> $middleware */
45
                    /** @var MiddlewareInterface $instance */
46
                    $instance = Container::create($middleware);
47
                } else {
48
                    $instance = $middleware;
49
                }
50
51
                return $instance->handle($request, $next);
52
            };
53
        };
54
    }
55
}
56