Completed
Push — master ( e6b663...fd87f3 )
by Edward
06:50
created

Runtime::populateIndexList()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 5
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 7
ccs 0
cts 5
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 fetchFilterContext(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 $matcher
78
    ): NodeValueListInterface {
79
        return $this
80
            ->valueListFetcher
81
            ->fetchChildren($values, $matcher);
82
    }
83
84
    public function fetchChildrenDeep(
85
        NodeValueListInterface $values,
86
        Matcher\ChildMatcherInterface $matcher
87
    ): NodeValueListInterface {
88
        return $this
89
            ->valueListFetcher
90
            ->fetchDeepChildren($values, $matcher);
91
    }
92
93
    public function matchAnyChild(): Matcher\ChildMatcherInterface
94
    {
95
        return new Matcher\AnyChildMatcher;
96
    }
97
98
    public function matchPropertyStrictly(string ...$nameList): Matcher\ChildMatcherInterface
99
    {
100
        return new Matcher\StrictPropertyMatcher(...$nameList);
101
    }
102
103
    public function matchElementStrictly(int ...$indexList): Matcher\ChildMatcherInterface
104
    {
105
        return new Matcher\StrictElementMatcher(...$indexList);
106
    }
107
108
    public function matchElementSlice(?int $start, ?int $end, ?int $step): Matcher\ChildMatcherInterface
109
    {
110
        return new Matcher\SliceElementMatcher($this->valueFetcher, $start, $end, $step);
111
    }
112
113
    public function populateLiteral(NodeValueListInterface $source, LiteralValueInterface $value): ValueListInterface
114
    {
115
        return new LiteralValueList($source->getIndexMap(), $value);
116
    }
117
118
    public function populateArrayElements(
119
        NodeValueListInterface $source,
120
        ValueListInterface ...$values
121
    ): array {
122
        foreach ($values as $valueList) {
123
            if (!$source->getIndexMap()->equals($valueList->getIndexMap())) {
124
                throw new Exception\IndexMapMatchFailedException($valueList, $source);
125
            }
126
        }
127
        $elementLists = array_fill_keys($source->getIndexMap()->getInnerIndice(), []);
128
        foreach ($values as $valueList) {
129
            foreach ($valueList->getValues() as $innerIndex => $value) {
130
                $elementLists[$innerIndex][] = $value;
131
            }
132
        }
133
134
        $createArrayElement = function (array $elements) use ($source): ValueInterface {
135
            return new LiteralArrayValue($source->getIndexMap(), ...$elements);
136
        };
137
138
        return array_map($createArrayElement, $elementLists);
139
    }
140
141
    public function createScalar($value): LiteralValueInterface
142
    {
143
        return new LiteralScalarValue($value);
144
    }
145
146
    public function createArray(ValueListInterface $source, ArrayValueInterface ...$elements): ValueListInterface
147
    {
148
        return new ValueList($source->getIndexMap(), ...$elements);
149
    }
150
}
151