Passed
Branch feature/first-release (4212f2)
by Andrea Marco
10:46
created

Tree::isDeep()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 2
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 2
rs 10
1
<?php
2
3
namespace Cerbero\JsonParser;
4
5
use Cerbero\JsonParser\Pointers\Pointers;
6
7
use function count;
8
9
/**
10
 * The JSON tree.
11
 *
12
 */
13
final class Tree
14
{
15
    /**
16
     * The original JSON tree.
17
     *
18
     * @var array<int, string|int>
19
     */
20
    private array $original = [];
21
22
    /**
23
     * The wildcarded JSON tree.
24
     *
25
     * @var array<int, string|int>
26
     */
27
    private array $wildcarded = [];
28
29
    /**
30
     * Whether a depth is within an object.
31
     *
32
     * @var array<int, bool>
33
     */
34
    private array $inObjectByDepth = [];
35
36
    /**
37
     * The JSON tree depth.
38
     *
39
     * @var int
40
     */
41
    private int $depth = -1;
42
43
    /**
44
     * Instantiate the class.
45
     *
46
     * @param Pointers $pointers
47
     */
48 131
    public function __construct(private Pointers $pointers)
49
    {
50 131
    }
51
52
    /**
53
     * Retrieve the original JSON tree
54
     *
55
     * @return array<int, string|int>
56
     */
57 87
    public function original(): array
58
    {
59 87
        return $this->original;
60
    }
61
62
    /**
63
     * Retrieve the wildcarded JSON tree
64
     *
65
     * @return array<int, string|int>
66
     */
67 80
    public function wildcarded(): array
68
    {
69 80
        return $this->wildcarded;
70
    }
71
72
    /**
73
     * Determine whether the current depth is within an object
74
     *
75
     * @return bool
76
     */
77 127
    public function inObject(): bool
78
    {
79 127
        return $this->inObjectByDepth[$this->depth] ?? false;
80
    }
81
82
    /**
83
     * Retrieve the JSON tree depth
84
     *
85
     * @return int
86
     */
87 87
    public function depth(): int
88
    {
89 87
        return $this->depth;
90
    }
91
92
    /**
93
     * Increase the tree depth by entering an object or an array
94
     *
95
     * @param bool $inObject
96
     * @return void
97
     */
98 127
    public function deepen(bool $inObject): void
99
    {
100 127
        $this->depth++;
101 127
        $this->inObjectByDepth[$this->depth] = $inObject;
102
    }
103
104
    /**
105
     * Decrease the tree depth
106
     *
107
     * @return void
108
     */
109 94
    public function emerge(): void
110
    {
111 94
        $this->depth--;
112
    }
113
114
    /**
115
     * Determine whether the tree is deep
116
     *
117
     * @return bool
118
     */
119 125
    public function isDeep(): bool
120
    {
121 125
        $pointer = $this->pointers->matching();
122
123 125
        return $pointer == '' ? $this->depth > $pointer->depth() : $this->depth >= $pointer->depth();
0 ignored issues
show
introduced by
The condition $pointer == '' is always false.
Loading history...
124
    }
125
126
    /**
127
     * Determine whether the tree should be tracked
128
     *
129
     * @return bool
130
     */
131 127
    public function shouldBeTracked(): bool
132
    {
133 127
        $pointer = $this->pointers->matching();
134
135 127
        return $pointer == '' || $this->depth() < $pointer->depth();
136
    }
137
138
    /**
139
     * Determine whether the tree is matched by the JSON pointer
140
     *
141
     * @return bool
142
     */
143 127
    public function isMatched(): bool
144
    {
145 127
        return $this->depth >= 0 && $this->pointers->matching()->matchesTree($this);
146
    }
147
148
    /**
149
     * Traverse the given object key
150
     *
151
     * @param string $key
152
     * @return void
153
     */
154 87
    public function traverseKey(string $key): void
155
    {
156 87
        $trimmedKey = substr($key, 1, -1);
157
158 87
        $this->original[$this->depth] = $trimmedKey;
159 87
        $this->wildcarded[$this->depth] = $trimmedKey;
160 87
        $this->pointers->matchTree($this);
161
    }
162
163
    /**
164
     * Traverse an array
165
     *
166
     * @return void
167
     */
168 127
    public function traverseArray(): void
169
    {
170 127
        $index = $this->original[$this->depth] ?? null;
171 127
        $this->original[$this->depth] = $index = is_int($index) ? $index + 1 : 0;
172
173 127
        if (count($this->original) > $this->depth + 1) {
174 127
            array_splice($this->original, $this->depth + 1);
175
        }
176
177 127
        $referenceTokens = $this->pointers->matchTree($this)->referenceTokens();
178 127
        $this->wildcarded[$this->depth] = ($referenceTokens[$this->depth] ?? null) == '-' ? '-' : $index;
179
180 127
        if (count($this->wildcarded) > $this->depth + 1) {
181 127
            array_splice($this->wildcarded, $this->depth + 1);
182
        }
183
    }
184
185
    /**
186
     * Retrieve the current key
187
     *
188
     * @return string|int
189
     */
190 93
    public function currentKey(): string|int
191
    {
192 93
        $key = $this->original[$this->depth];
193
194 93
        return is_string($key) ? "\"$key\"" : $key;
195
    }
196
}
197