Query::findAll()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 4
nop 2
dl 0
loc 16
ccs 9
cts 9
cp 1
crap 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the league/commonmark package.
7
 *
8
 * (c) Colin O'Dell <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace League\CommonMark\Node;
15
16
use League\CommonMark\Node\Query\AndExpr;
17
use League\CommonMark\Node\Query\OrExpr;
18
19
final class Query
20
{
21
    /** @var callable(Node): bool $condition */
22
    private $condition;
23
24 72
    public function __construct()
25
    {
26 72
        $this->condition = new AndExpr();
27
    }
28
29 68
    public function where(callable ...$conditions): self
30
    {
31 68
        return $this->andWhere(...$conditions);
32
    }
33
34 68
    public function andWhere(callable ...$conditions): self
35
    {
36 68
        if ($this->condition instanceof AndExpr) {
37 68
            foreach ($conditions as $condition) {
38 68
                $this->condition->add($condition);
39
            }
40
        } else {
41 4
            $this->condition = new AndExpr($this->condition, ...$conditions);
42
        }
43
44 68
        return $this;
45
    }
46
47 6
    public function orWhere(callable ...$conditions): self
48
    {
49 6
        if ($this->condition instanceof OrExpr) {
50 2
            foreach ($conditions as $condition) {
51 2
                $this->condition->add($condition);
52
            }
53
        } else {
54 6
            $this->condition = new OrExpr($this->condition, ...$conditions);
55
        }
56
57 6
        return $this;
58
    }
59
60 6
    public function findOne(Node $node): ?Node
61
    {
62 6
        foreach ($node->iterator() as $n) {
63 6
            if (\call_user_func($this->condition, $n)) {
64 4
                return $n;
65
            }
66
        }
67
68 2
        return null;
69
    }
70
71
    /**
72
     * @return iterable<Node>
73
     */
74 66
    public function findAll(Node $node, ?int $limit = PHP_INT_MAX): iterable
75
    {
76 66
        $resultCount = 0;
77
78 66
        foreach ($node->iterator() as $n) {
79 66
            if ($resultCount >= $limit) {
80 2
                break;
81
            }
82
83 66
            if (! \call_user_func($this->condition, $n)) {
84 64
                continue;
85
            }
86
87 52
            ++$resultCount;
88
89 52
            yield $n;
90
        }
91
    }
92
93
    /**
94
     * @return callable(Node): bool
95
     */
96 54
    public static function type(string $class): callable
97
    {
98 54
        return static fn (Node $node): bool => $node instanceof $class;
99
    }
100
101
    /**
102
     * @psalm-param ?callable(Node): bool $condition
103
     *
104
     * @return callable(Node): bool
105
     */
106 8
    public static function hasChild(?callable $condition = null): callable
107
    {
108 8
        return static function (Node $node) use ($condition): bool {
109 8
            foreach ($node->children() as $child) {
110 8
                if ($condition === null || $condition($child)) {
111 8
                    return true;
112
                }
113
            }
114
115 8
            return false;
116 8
        };
117
    }
118
119
    /**
120
     * @psalm-param ?callable(Node): bool $condition
121
     *
122
     * @return callable(Node): bool
123
     */
124 12
    public static function hasParent(?callable $condition = null): callable
125
    {
126 12
        return static function (Node $node) use ($condition): bool {
127 12
            $parent = $node->parent();
128 12
            if ($parent === null) {
129 12
                return false;
130
            }
131
132 10
            if ($condition === null) {
133 8
                return true;
134
            }
135
136 2
            return $condition($parent);
137 12
        };
138
    }
139
}
140