Passed
Branch master (16734b)
by Edward
06:30 queued 02:11
created

LazyQuery::createOperationDataIterator()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 7
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace Remorhaz\JSON\Patch\Query;
5
6
use Iterator;
7
use Remorhaz\JSON\Data\Export\ValueDecoderInterface;
8
use Remorhaz\JSON\Data\Export\ValueEncoderInterface;
9
use Remorhaz\JSON\Data\Value\ArrayValueInterface;
10
use Remorhaz\JSON\Data\Value\NodeValueInterface;
11
use Remorhaz\JSON\Patch\Operation\OperationFactoryInterface;
12
use Remorhaz\JSON\Patch\Result\ResultInterface;
13
use Remorhaz\JSON\Pointer\Processor\ProcessorInterface as PointerProcessorInterface;
14
use Throwable;
15
16
final class LazyQuery implements QueryInterface
17
{
18
19
    private $operationFactory;
20
21
    private $encoder;
22
23
    private $decoder;
24
25
    private $patch;
26
27
    private $loadedQuery;
28
29
    public function __construct(
30
        OperationFactoryInterface $operationFactory,
31
        ValueEncoderInterface $encoder,
32
        ValueDecoderInterface $decoder,
33
        NodeValueInterface $patch
34
    ) {
35
        $this->operationFactory = $operationFactory;
36
        $this->encoder = $encoder;
37
        $this->decoder = $decoder;
38
        $this->patch = $patch;
39
    }
40
41
    public function __invoke(NodeValueInterface $data, PointerProcessorInterface $pointerProcessor): ResultInterface
42
    {
43
        return $this->getLoadedQuery()($data, $pointerProcessor);
44
    }
45
46
    private function getLoadedQuery(): QueryInterface
47
    {
48
        if (!isset($this->loadedQuery)) {
49
            $this->loadedQuery = $this->loadQuery();
50
        }
51
52
        return $this->loadedQuery;
53
    }
54
55
    private function loadQuery(): QueryInterface
56
    {
57
        $operations = [];
58
        try {
59
            foreach ($this->createOperationDataIterator($this->patch) as $index => $operationData) {
60
                $operations[] = $this
61
                    ->operationFactory
62
                    ->fromJson($operationData, $index);
63
            }
64
        } catch (Throwable $e) {
65
            throw new Exception\PatchNotLoadedException($this->patch, $e);
66
        }
67
68
        return new Query($this->encoder, $this->decoder, ...$operations);
69
    }
70
71
    private function createOperationDataIterator(NodeValueInterface $patch): Iterator
72
    {
73
        if ($patch instanceof ArrayValueInterface) {
74
            return $patch->createChildIterator();
75
        }
76
77
        throw new Exception\InvalidPatchException($patch);
78
    }
79
}
80