Completed
Push — master ( 113bfa...89e2e4 )
by Edward
07:06
created

Runtime::populateArrayElements()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 10
nc 7
nop 2
dl 0
loc 21
ccs 0
cts 11
cp 0
crap 30
rs 9.6111
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Remorhaz\JSON\Path\Runtime;
5
6
use Remorhaz\JSON\Data\Value\ArrayValueInterface;
7
use Remorhaz\JSON\Data\Value\ValueInterface;
8
use Remorhaz\JSON\Path\Value\EvaluatedValueList;
9
use Remorhaz\JSON\Path\Value\EvaluatedValueListInterface;
10
use Remorhaz\JSON\Path\Value\IndexMap;
11
use Remorhaz\JSON\Path\Value\LiteralArrayValue;
12
use Remorhaz\JSON\Path\Value\LiteralArrayValueList;
13
use Remorhaz\JSON\Path\Value\LiteralScalarValue;
14
use Remorhaz\JSON\Path\Value\LiteralValueInterface;
15
use Remorhaz\JSON\Path\Value\LiteralValueList;
16
use Remorhaz\JSON\Data\Value\NodeValueInterface;
17
use Remorhaz\JSON\Path\Value\NodeValueList;
18
use Remorhaz\JSON\Path\Value\NodeValueListInterface;
19
use Remorhaz\JSON\Path\Value\ValueListInterface;
20
21
final class Runtime implements RuntimeInterface
22
{
23
24
    private $fetcher;
25
26
    private $evaluator;
27
28
    public function __construct(Fetcher $fetcher, Evaluator $evaluator)
29
    {
30
        $this->fetcher = $fetcher;
31
        $this->evaluator = $evaluator;
32
    }
33
34
    public function getInput(NodeValueInterface $rootValue): NodeValueListInterface
35
    {
36
        return new NodeValueList(new IndexMap(0), $rootValue);
37
    }
38
39
    public function createFilterContext(NodeValueListInterface $values): NodeValueListInterface
40
    {
41
        return $this
42
            ->fetcher
43
            ->fetchFilterContext($values);
44
    }
45
46
    public function split(NodeValueListInterface $values): NodeValueListInterface
47
    {
48
        return new NodeValueList(
49
            $values->getIndexMap()->split(),
50
            ...$values->getValues()
51
        );
52
    }
53
54
    public function evaluate(ValueListInterface $source, ValueListInterface $values): EvaluatedValueListInterface
55
    {
56
        return $this
57
            ->evaluator
58
            ->evaluate($source, $values);
59
    }
60
61
    public function filter(
62
        NodeValueListInterface $contextValues,
63
        EvaluatedValueListInterface $evaluatedValues
64
    ): NodeValueListInterface {
65
        return $this
66
            ->fetcher
67
            ->filterValues(
68
                new ValueListFilter(
69
                    new EvaluatedValueList(
70
                        $evaluatedValues->getIndexMap()->join($contextValues->getIndexMap()),
71
                        ...$evaluatedValues->getResults()
72
                    )
73
                ),
74
                $contextValues
75
            );
76
    }
77
78
    public function evaluateLogicalOr(
79
        EvaluatedValueListInterface $leftValues,
80
        EvaluatedValueListInterface $rightValues
81
    ): EvaluatedValueListInterface {
82
        return $this
83
            ->evaluator
84
            ->logicalOr($leftValues, $rightValues);
85
    }
86
87
    public function evaluateLogicalAnd(
88
        EvaluatedValueListInterface $leftValues,
89
        EvaluatedValueListInterface $rightValues
90
    ): EvaluatedValueListInterface {
91
        return $this
92
            ->evaluator
93
            ->logicalAnd($leftValues, $rightValues);
94
    }
95
96
    public function evaluateLogicalNot(EvaluatedValueListInterface $values): EvaluatedValueListInterface
97
    {
98
        return $this
99
            ->evaluator
100
            ->logicalNot($values);
101
    }
102
103
    public function calculateIsEqual(
104
        ValueListInterface $leftValues,
105
        ValueListInterface $rightValues
106
    ): ValueListInterface {
107
        return $this
108
            ->evaluator
109
            ->isEqual($leftValues, $rightValues);
110
    }
111
112
    public function calculateIsGreater(
113
        ValueListInterface $leftValues,
114
        ValueListInterface $rightValues
115
    ): ValueListInterface {
116
        return $this
117
            ->evaluator
118
            ->isGreater($leftValues, $rightValues);
119
    }
120
121
    public function calculateIsRegExp(string $pattern, ValueListInterface $values): ValueListInterface
122
    {
123
        return $this
124
            ->evaluator
125
            ->isRegExp($values, $pattern); // TODO: Make arguments order consistent
126
    }
127
128
    public function fetchChildren(
129
        NodeValueListInterface $values,
130
        Matcher\ChildMatcherInterface ...$matchers
131
    ): NodeValueListInterface {
132
        return $this
133
            ->fetcher
134
            ->fetchChildren($values, ...$matchers);
135
    }
136
137
    public function fetchChildrenDeep(
138
        NodeValueListInterface $values,
139
        Matcher\ChildMatcherInterface $matcher
140
    ): NodeValueListInterface {
141
        return $this
142
            ->fetcher
143
            ->fetchDeepChildren($matcher, $values);
144
    }
145
146
    public function matchAnyChild(NodeValueListInterface $source): array
147
    {
148
        return array_map(
149
            function (): Matcher\ChildMatcherInterface {
150
                return new Matcher\AnyChildMatcher;
151
            },
152
            $source->getIndexMap()->getInnerIndice()
153
        );
154
    }
155
156
    public function matchPropertyStrictly(array $nameLists): array
157
    {
158
        return array_map(
159
            function (array $nameList): Matcher\ChildMatcherInterface {
160
                return new Matcher\StrictPropertyMatcher(...$nameList);
161
            },
162
            $nameLists
163
        );
164
    }
165
166
    public function matchElementStrictly(array $indexLists): array
167
    {
168
        return array_map(
169
            function (array $indexList): Matcher\ChildMatcherInterface {
170
                return new Matcher\StrictElementMatcher(...$indexList);
171
            },
172
            $indexLists
173
        );
174
    }
175
176
    public function aggregate(string $name, NodeValueListInterface $values): ValueListInterface
177
    {
178
        return $this
179
            ->evaluator
180
            ->aggregate($name, $values);
181
    }
182
183
    public function populateLiteral(NodeValueListInterface $source, LiteralValueInterface $value): ValueListInterface
184
    {
185
        return new LiteralValueList($source->getIndexMap(), $value);
186
    }
187
188
    public function populateArrayElements(
189
        NodeValueListInterface $source,
190
        ValueListInterface ...$values
191
    ): array {
192
        foreach ($values as $valueList) {
193
            if (!$source->getIndexMap()->equals($valueList->getIndexMap())) {
194
                throw new Exception\IndexMapMatchFailedException($valueList, $source);
195
            }
196
        }
197
        $elementLists = array_fill_keys($source->getIndexMap()->getInnerIndice(), []);
198
        foreach ($values as $valueList) {
199
            foreach ($valueList->getValues() as $innerIndex => $value) {
200
                $elementLists[$innerIndex][] = $value;
201
            }
202
        }
203
204
        $createArrayElement = function (array $elements) use ($source): ValueInterface {
205
            return new LiteralArrayValue($source->getIndexMap(), ...$elements);
206
        };
207
208
        return array_map($createArrayElement, $elementLists);
209
    }
210
211
    public function populateIndexList(NodeValueListInterface $source, int ...$indexList): array
212
    {
213
        return array_fill_keys(
214
            $source
215
                ->getIndexMap()
216
                ->getInnerIndice(),
217
            $indexList
218
        );
219
    }
220
221
    public function populateIndexSlice(NodeValueListInterface $source, ?int $start, ?int $end, ?int $step): array
222
    {
223
        return $this
224
            ->fetcher
225
            ->fetchSliceIndice($source, $start, $end, $step);
226
    }
227
228
    public function populateNameList(NodeValueListInterface $source, string ...$nameList): array
229
    {
230
        return array_fill_keys(
231
            $source
232
                ->getIndexMap()
233
                ->getInnerIndice(),
234
            $nameList
235
        );
236
    }
237
238
    public function createScalar($value): LiteralValueInterface
239
    {
240
        return new LiteralScalarValue($value);
241
    }
242
243
    public function createArray(ValueListInterface $source, ArrayValueInterface ...$elements): ValueListInterface
244
    {
245
        return new LiteralArrayValueList($source->getIndexMap(), ...$elements);
246
    }
247
}
248