Completed
Push — latest ( ca3ef7...2db11b )
by Colin
15s queued 10s
created

Query::hasChild()   A

Complexity

Conditions 4
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 10
ccs 6
cts 6
cp 1
rs 10
cc 4
nc 1
nop 1
crap 4
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 33
    public function __construct()
25
    {
26 33
        $this->condition = new AndExpr();
27 33
    }
28
29 27
    public function where(callable ...$conditions): self
30
    {
31 27
        return $this->andWhere(...$conditions);
32
    }
33
34 27
    public function andWhere(callable ...$conditions): self
35
    {
36 27
        if ($this->condition instanceof AndExpr) {
37 27
            foreach ($conditions as $condition) {
38 27
                $this->condition->add($condition);
39
            }
40
        } else {
41 6
            $this->condition = new AndExpr($this->condition, ...$conditions);
42
        }
43
44 27
        return $this;
45
    }
46
47 9
    public function orWhere(callable ...$conditions): self
48
    {
49 9
        if ($this->condition instanceof OrExpr) {
50 3
            foreach ($conditions as $condition) {
51 3
                $this->condition->add($condition);
52
            }
53
        } else {
54 9
            $this->condition = new OrExpr($this->condition, ...$conditions);
55
        }
56
57 9
        return $this;
58
    }
59
60 9
    public function findOne(Node $node): ?Node
61
    {
62 9
        $walker = $node->walker();
63 9
        while ($event = $walker->next()) {
64 9
            if (! $event->isEntering()) {
65 3
                continue;
66
            }
67
68 9
            if (\call_user_func($this->condition, $node = $event->getNode())) {
69 6
                return $node;
70
            }
71
        }
72
73 3
        return null;
74
    }
75
76
    /**
77
     * @return iterable<Node>
78
     */
79 24
    public function findAll(Node $node, ?int $limit = PHP_INT_MAX): iterable
80
    {
81
        /** @var Node[] $results */
82 24
        $results     = [];
83 24
        $resultCount = 0;
84
85 24
        $walker = $node->walker();
86 24
        while ($event = $walker->next()) {
87 24
            if (! $event->isEntering()) {
88 21
                continue;
89
            }
90
91 24
            if (\call_user_func($this->condition, $event->getNode())) {
92 21
                $results[] = $event->getNode();
93 21
                ++$resultCount;
94
            }
95
96 24
            if ($resultCount >= $limit) {
97 3
                break;
98
            }
99
        }
100
101 24
        return $results;
102
    }
103
104
    /**
105
     * @return callable(Node): bool
106
     */
107 6
    public static function type(string $class): callable
108
    {
109 4
        return static function (Node $node) use ($class): bool {
110 6
            return $node instanceof $class;
111 6
        };
112
    }
113
114
    /**
115
     * @param ?callable $condition
116
     *
117
     * @psalm-param ?callable(Node): bool $condition
118
     *
119
     * @return callable(Node): bool
120
     */
121 12
    public static function hasChild(?callable $condition = null): callable
122
    {
123 8
        return static function (Node $node) use ($condition): bool {
124 12
            foreach ($node->children() as $child) {
125 12
                if ($condition === null || $condition($child)) {
126 12
                    return true;
127
                }
128
            }
129
130 12
            return false;
131 12
        };
132
    }
133
134
    /**
135
     * @param ?callable $condition
136
     *
137
     * @psalm-param ?callable(Node): bool $condition
138
     *
139
     * @return callable(Node): bool
140
     */
141 18
    public static function hasParent(?callable $condition = null): callable
142
    {
143 12
        return static function (Node $node) use ($condition): bool {
144 18
            $parent = $node->parent();
145 18
            if ($parent === null) {
146 18
                return false;
147
            }
148
149 15
            if ($condition === null) {
150 12
                return true;
151
            }
152
153 3
            return $condition($parent);
154 18
        };
155
    }
156
}
157