Matching::__invoke()   A
last analyzed

Complexity

Conditions 5
Paths 1

Size

Total Lines 38
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 5

Importance

Changes 3
Bugs 2 Features 2
Metric Value
cc 5
eloc 18
c 3
b 2
f 2
nc 1
nop 0
dl 0
loc 38
ccs 19
cts 19
cp 1
crap 5
rs 9.3554
1
<?php
2
3
declare(strict_types=1);
4
5
namespace loophp\collection\Operation;
6
7
use Closure;
8
use Doctrine\Common\Collections\Criteria;
9
use Doctrine\Common\Collections\Expr\ClosureExpressionVisitor;
10
use Doctrine\Common\Collections\Order;
11
use Generator;
12
use loophp\collection\Contract\Operation\Sortable;
13
14
/**
15
 * @immutable
16
 *
17
 * @template TKey
18
 * @template T
19
 */
20
final class Matching extends AbstractOperation
21
{
22
    /**
23
     * @return Closure(Criteria): Closure(iterable<TKey, T>): Generator<TKey, T>
24
     */
25 2
    public function __invoke(): Closure
26
    {
27 2
        return
28
            /**
29
             * @return Closure(iterable<TKey, T>): Generator<TKey, T>
30
             */
31 2
            static function (Criteria $criteria): Closure {
32 2
                $expr = $criteria->getWhereExpression();
33 2
                $pipes = [];
34
35 2
                if (null !== $expr) {
36
                    /** @var Closure(T): bool $filterCallback */
37 2
                    $filterCallback = (new ClosureExpressionVisitor())->dispatch($expr);
38 2
                    $pipes[] = (new Filter())()($filterCallback);
39
                }
40
41 2
                $orderings = $criteria->orderings();
42
43 2
                if ([] !== $orderings) {
44 2
                    $next = null;
45
46 2
                    foreach (array_reverse($orderings) as $field => $ordering) {
47 2
                        $next = ClosureExpressionVisitor::sortByField($field, Order::Descending === $ordering ? -1 : 1, $next);
48
                    }
49
50 2
                    $pipes[] = (new Sort())()(Sortable::BY_VALUES)($next);
51
                }
52
53 2
                $offset = $criteria->getFirstResult();
54 2
                $length = $criteria->getMaxResults();
55
56 2
                $pipes[] = (new Limit())()($length ?? -1)($offset ?? 0);
57
58
                /** @var Closure(iterable<TKey, T>): Generator<TKey, T> $pipe */
59 2
                $pipe = (new Pipe())()(...$pipes);
60
61
                // Point free style.
62 2
                return $pipe;
63 2
            };
64
    }
65
}
66