ValueFetcher   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 31
dl 0
loc 81
ccs 0
cts 37
cp 0
rs 10
c 2
b 0
f 0
wmc 17

4 Methods

Rating   Name   Duplication   Size   Complexity  
A createSortedChildStructIterator() 0 17 4
A createChildrenIterator() 0 17 4
A createDeepChildrenIterator() 0 20 5
A createUnsortedChildStructIterator() 0 11 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Remorhaz\JSON\Path\Runtime;
6
7
use Iterator;
8
use Remorhaz\JSON\Data\Value\StructValueInterface;
9
use Remorhaz\JSON\Data\Value\NodeValueInterface;
10
use Remorhaz\JSON\Data\Value\ScalarValueInterface;
11
use Remorhaz\JSON\Path\Runtime\Matcher\SortedChildMatcherInterface;
12
13
use function ksort;
14
15
use const SORT_ASC;
16
use const SORT_NUMERIC;
17
18
final class ValueFetcher implements ValueFetcherInterface
19
{
20
21
    /**
22
     * @param Matcher\ChildMatcherInterface $matcher
23
     * @param NodeValueInterface            $value
24
     * @return NodeValueInterface[]|Iterator
25
     */
26
    public function createChildrenIterator(
27
        Matcher\ChildMatcherInterface $matcher,
28
        NodeValueInterface $value
29
    ): Iterator {
30
        if ($value instanceof ScalarValueInterface) {
31
            return;
32
        }
33
34
        if ($value instanceof StructValueInterface) {
35
            yield from $matcher instanceof SortedChildMatcherInterface
36
                ? $this->createSortedChildStructIterator($matcher, $value)
37
                : $this->createUnsortedChildStructIterator($matcher, $value);
38
39
            return;
40
        }
41
42
        throw new Exception\UnexpectedNodeValueFetchedException($value);
43
    }
44
45
    private function createUnsortedChildStructIterator(
46
        Matcher\ChildMatcherInterface $matcher,
47
        NodeValueInterface $value
48
    ): Iterator {
49
        if (!$value instanceof StructValueInterface) {
50
            return;
51
        }
52
53
        foreach ($value->createChildIterator() as $index => $element) {
54
            if ($matcher->match($index, $element, $value)) {
55
                yield $element;
56
            }
57
        }
58
    }
59
60
    private function createSortedChildStructIterator(
61
        Matcher\SortedChildMatcherInterface $matcher,
62
        NodeValueInterface $value
63
    ): Iterator {
64
        if (!$value instanceof StructValueInterface) {
65
            return;
66
        }
67
68
        $sortableElements = [];
69
        foreach ($value->createChildIterator() as $index => $element) {
70
            if ($matcher->match($index, $element, $value)) {
71
                $sortIndex = $matcher->getSortIndex($index, $element, $value);
72
                $sortableElements[$sortIndex] = $element;
73
            }
74
        }
75
        ksort($sortableElements, SORT_ASC | SORT_NUMERIC);
76
        yield from $sortableElements;
77
    }
78
79
    public function createDeepChildrenIterator(
80
        Matcher\ChildMatcherInterface $matcher,
81
        NodeValueInterface $value
82
    ): Iterator {
83
        if ($value instanceof ScalarValueInterface) {
84
            return;
85
        }
86
87
        if ($value instanceof StructValueInterface) {
88
            foreach ($value->createChildIterator() as $index => $element) {
89
                if ($matcher->match($index, $element, $value)) {
90
                    yield $element;
91
                }
92
                yield from $this->createDeepChildrenIterator($matcher, $element);
93
            }
94
95
            return;
96
        }
97
98
        throw new Exception\UnexpectedNodeValueFetchedException($value);
99
    }
100
}
101