Passed
Pull Request — main (#40)
by Jesús
03:27
created

MiddlewarePipeline   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 39
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 39
rs 10
c 1
b 0
f 0
eloc 12
wmc 4

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A handle() 0 14 1
A carry() 0 13 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