Passed
Push — master ( bae1fe...e6b663 )
by Edward
04:30
created

Runtime::fetchChildren()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 7
ccs 0
cts 3
cp 0
crap 2
rs 10
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\LiteralArrayValue;
11
use Remorhaz\JSON\Path\Value\ValueList;
12
use Remorhaz\JSON\Path\Value\LiteralScalarValue;
13
use Remorhaz\JSON\Path\Value\LiteralValueInterface;
14
use Remorhaz\JSON\Path\Value\LiteralValueList;
15
use Remorhaz\JSON\Data\Value\NodeValueInterface;
16
use Remorhaz\JSON\Path\Value\NodeValueList;
17
use Remorhaz\JSON\Path\Value\NodeValueListBuilder;
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 $valueListFetcher;
25
26
    private $valueFetcher;
27
28
    public function __construct(ValueListFetcher $valueListFetcher, ValueFetcherInterface $valueFetcher)
29
    {
30
        $this->valueListFetcher = $valueListFetcher;
31
        $this->valueFetcher = $valueFetcher;
32
    }
33
34
    public function getInput(NodeValueInterface $rootValue): NodeValueListInterface
35
    {
36
        return (new NodeValueListBuilder)
37
            ->addValue($rootValue, 0)
38
            ->build();
39
    }
40
41
    public function createFilterContext(NodeValueListInterface $values): NodeValueListInterface
42
    {
43
        return $this
44
            ->valueListFetcher
45
            ->fetchFilterContext($values);
46
    }
47
48
    public function splitFilterContext(NodeValueListInterface $values): NodeValueListInterface
49
    {
50
        return new NodeValueList(
51
            $values->getIndexMap()->split(),
52
            ...$values->getValues()
53
        );
54
    }
55
56
    public function joinFilterResults(
57
        EvaluatedValueListInterface $evaluatedValues,
58
        NodeValueListInterface $contextValues
59
    ): EvaluatedValueListInterface {
60
        return new EvaluatedValueList(
61
            $evaluatedValues->getIndexMap()->join($contextValues->getIndexMap()),
62
            ...$evaluatedValues->getResults()
63
        );
64
    }
65
66
    public function fetchFilteredValues(
67
        NodeValueListInterface $contextValues,
68
        EvaluatedValueListInterface $evaluatedValues
69
    ): NodeValueListInterface {
70
        return $this
71
            ->valueListFetcher
72
            ->fetchFilteredValues($evaluatedValues, $contextValues);
73
    }
74
75
    public function fetchChildren(
76
        NodeValueListInterface $values,
77
        Matcher\ChildMatcherInterface ...$matchers
78
    ): NodeValueListInterface {
79
        return $this
80
            ->valueListFetcher
81
            ->fetchChildren($values, ...$matchers);
82
    }
83
84
    public function fetchChildrenDeep(
85
        NodeValueListInterface $values,
86
        Matcher\ChildMatcherInterface $matcher
87
    ): NodeValueListInterface {
88
        return $this
89
            ->valueListFetcher
90
            ->fetchDeepChildren($matcher, $values);
91
    }
92
93
    public function matchAnyChild(NodeValueListInterface $source): array
94
    {
95
        return array_map(
96
            function (): Matcher\ChildMatcherInterface {
97
                return new Matcher\AnyChildMatcher;
98
            },
99
            $source->getIndexMap()->getInnerIndice()
100
        );
101
    }
102
103
    public function matchPropertyStrictly(array $nameLists): array
104
    {
105
        return array_map(
106
            function (array $nameList): Matcher\ChildMatcherInterface {
107
                return new Matcher\StrictPropertyMatcher(...$nameList);
108
            },
109
            $nameLists
110
        );
111
    }
112
113
    public function matchElementStrictly(array $indexLists): array
114
    {
115
        return array_map(
116
            function (array $indexList): Matcher\ChildMatcherInterface {
117
                return new Matcher\StrictElementMatcher(...$indexList);
118
            },
119
            $indexLists
120
        );
121
    }
122
123
    public function matchElementSlice(NodeValueListInterface $source, ?int $start, ?int $end, ?int $step): array
124
    {
125
        return array_map(
126
            function () use ($start, $end, $step): Matcher\ChildMatcherInterface {
127
                return new Matcher\SliceElementMatcher($this->valueFetcher, $start, $end, $step);
128
            },
129
            $source->getIndexMap()->getInnerIndice()
130
        );
131
    }
132
133
    public function populateLiteral(NodeValueListInterface $source, LiteralValueInterface $value): ValueListInterface
134
    {
135
        return new LiteralValueList($source->getIndexMap(), $value);
136
    }
137
138
    public function populateArrayElements(
139
        NodeValueListInterface $source,
140
        ValueListInterface ...$values
141
    ): array {
142
        foreach ($values as $valueList) {
143
            if (!$source->getIndexMap()->equals($valueList->getIndexMap())) {
144
                throw new Exception\IndexMapMatchFailedException($valueList, $source);
145
            }
146
        }
147
        $elementLists = array_fill_keys($source->getIndexMap()->getInnerIndice(), []);
148
        foreach ($values as $valueList) {
149
            foreach ($valueList->getValues() as $innerIndex => $value) {
150
                $elementLists[$innerIndex][] = $value;
151
            }
152
        }
153
154
        $createArrayElement = function (array $elements) use ($source): ValueInterface {
155
            return new LiteralArrayValue($source->getIndexMap(), ...$elements);
156
        };
157
158
        return array_map($createArrayElement, $elementLists);
159
    }
160
161
    public function populateIndexList(NodeValueListInterface $source, int ...$indexList): array
162
    {
163
        return array_fill_keys(
164
            $source
165
                ->getIndexMap()
166
                ->getInnerIndice(),
167
            $indexList
168
        );
169
    }
170
171
    public function populateNameList(NodeValueListInterface $source, string ...$nameList): array
172
    {
173
        return array_fill_keys(
174
            $source
175
                ->getIndexMap()
176
                ->getInnerIndice(),
177
            $nameList
178
        );
179
    }
180
181
    public function createScalar($value): LiteralValueInterface
182
    {
183
        return new LiteralScalarValue($value);
184
    }
185
186
    public function createArray(ValueListInterface $source, ArrayValueInterface ...$elements): ValueListInterface
187
    {
188
        return new ValueList($source->getIndexMap(), ...$elements);
189
    }
190
}
191