Completed
Push — master ( 37a545...2ac5c4 )
by Edward
04:29
created

Runtime::populateIndexSlice()   A

Complexity

Conditions 1
Paths 1

Size

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