Skip to content

Commit a295b4d

Browse files
committed
New evaluator refactored into set of operation classes.
1 parent 2b85b7e commit a295b4d

14 files changed

+483
-231
lines changed

src/Data/Raw.php src/Data/RawWriter.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Remorhaz\JSONPointer\Data;
44

5-
class Raw implements WriterInterface, SelectorInterface
5+
class RawWriter implements SelectableWriterInterface
66
{
77

88
/**

src/Data/SelectorInterface.php src/Data/SelectableInterface.php

+22-7
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,33 @@
22

33
namespace Remorhaz\JSONPointer\Data;
44

5-
interface SelectorInterface {
5+
interface SelectableInterface extends ReaderInterface
6+
{
67

78

9+
/**
10+
* @return $this
11+
*/
812
public function selectRoot();
913

1014

15+
/**
16+
* @param string $property
17+
* @return $this
18+
*/
1119
public function selectProperty(string $property);
1220

1321

22+
/**
23+
* @param int $index
24+
* @return $this
25+
*/
1426
public function selectIndex(int $index);
1527

1628

29+
/**
30+
* @return $this
31+
*/
1732
public function selectNewIndex();
1833

1934

@@ -33,13 +48,13 @@ public function isBooleanSelected(): bool;
3348

3449

3550
public function isNullSelected(): bool;
36-
37-
51+
52+
3853
public function isPropertySelected(): bool;
39-
40-
54+
55+
4156
public function isIndexSelected(): bool;
42-
43-
57+
58+
4459
public function isNewIndexSelected(): bool;
4560
}
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Remorhaz\JSONPointer\Data;
4+
5+
interface SelectableReaderInterface extends ReaderInterface, SelectableInterface
6+
{
7+
}
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Remorhaz\JSONPointer\Data;
4+
5+
interface SelectableWriterInterface extends SelectableReaderInterface, WriterInterface
6+
{
7+
}

src/Evaluator/Operation.php

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace Remorhaz\JSONPointer\Evaluator;
4+
5+
use Remorhaz\JSONPointer\Locator\Locator;
6+
use Remorhaz\JSONPointer\Locator\Reference;
7+
8+
abstract class Operation
9+
{
10+
11+
protected $locator;
12+
13+
protected $result;
14+
15+
protected $isResultSet = false;
16+
17+
18+
public function __construct(Locator $locator)
19+
{
20+
$this->locator = $locator;
21+
}
22+
23+
24+
/**
25+
* Tries to apply given reference to data selector.
26+
*
27+
* @param Reference $reference
28+
* @return $this
29+
*/
30+
abstract protected function applyReference(Reference $reference);
31+
32+
33+
/**
34+
* @return $this
35+
*/
36+
public function perform()
37+
{
38+
foreach ($this->locator->getReferenceList() as $reference) {
39+
$this->applyReference($reference);
40+
if ($this->isResultSet()) {
41+
break;
42+
}
43+
}
44+
return $this;
45+
}
46+
47+
48+
public function getResult()
49+
{
50+
if (!$this->isResultSet()) {
51+
throw new LogicException("Operation result is not set");
52+
}
53+
return $this->result;
54+
}
55+
56+
57+
protected function setResult($result)
58+
{
59+
$this->result = $result;
60+
$this->isResultSet = true;
61+
return $this;
62+
}
63+
64+
65+
protected function isResultSet(): bool
66+
{
67+
return $this->isResultSet;
68+
}
69+
}

src/Evaluator/OperationDelete.php

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
namespace Remorhaz\JSONPointer\Evaluator;
4+
5+
use Remorhaz\JSONPointer\Data\SelectableWriterInterface;
6+
use Remorhaz\JSONPointer\Locator\Locator;
7+
use Remorhaz\JSONPointer\Locator\Reference;
8+
9+
class OperationDelete extends Operation
10+
{
11+
12+
protected $writer;
13+
14+
15+
public function __construct(Locator $locator, SelectableWriterInterface $writer)
16+
{
17+
parent::__construct($locator);
18+
$this->writer = $writer;
19+
}
20+
21+
22+
public function perform()
23+
{
24+
if (empty($this->locator->getReferenceList())) {
25+
throw new EvaluatorException("Data root can't be deleted");
26+
}
27+
parent::perform();
28+
if ($this->writer->isIndexSelected()) {
29+
$this->writer->removeElement();
30+
} elseif ($this->writer->isPropertySelected()) {
31+
$this->writer->removeProperty();
32+
} else {
33+
throw new LogicException("Failed to remove data at '{$this->locator->getText()}'");
34+
}
35+
return $this;
36+
}
37+
38+
39+
protected function applyReference(Reference $reference)
40+
{
41+
if ($this->writer->isArraySelected()) {
42+
if ($reference->getType() != $reference::TYPE_INDEX) {
43+
throw new EvaluatorException(
44+
"Invalid index '{$reference->getKey()}' at '{$reference->getPath()}''"
45+
);
46+
}
47+
$index = (int) $reference->getKey();
48+
$this->writer->selectIndex($index);
49+
if (!$this->writer->hasData()) {
50+
throw new EvaluatorException("No element #{$index} at '{$reference->getPath()}'");
51+
}
52+
} elseif ($this->writer->isObjectSelected()) {
53+
$property = (string) $reference->getKey();
54+
$this->writer->selectProperty($property);
55+
if (!$this->writer->hasData()) {
56+
throw new EvaluatorException("No property '{$property}' at '{$reference->getPath()}'");
57+
}
58+
} else {
59+
throw new EvaluatorException("Scalar data at '{$reference->getPath()}'");
60+
}
61+
return $this;
62+
}
63+
}

src/Evaluator/OperationRead.php

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
namespace Remorhaz\JSONPointer\Evaluator;
4+
5+
use Remorhaz\JSONPointer\Data\SelectableReaderInterface;
6+
use Remorhaz\JSONPointer\Locator\Locator;
7+
use Remorhaz\JSONPointer\Locator\Reference;
8+
9+
class OperationRead extends Operation
10+
{
11+
12+
protected $reader;
13+
14+
15+
public function __construct(Locator $locator, SelectableReaderInterface $reader)
16+
{
17+
parent::__construct($locator);
18+
$this->reader = $reader;
19+
}
20+
21+
22+
public function perform()
23+
{
24+
return parent::perform()
25+
->setResult($this->reader->getData());
26+
}
27+
28+
29+
protected function applyReference(Reference $reference)
30+
{
31+
if ($this->reader->isArraySelected()) {
32+
if ($reference->getType() != $reference::TYPE_INDEX) {
33+
throw new EvaluatorException(
34+
"Invalid index '{$reference->getKey()}' at {$reference->getPath()}"
35+
);
36+
}
37+
$index = (int) $reference->getKey();
38+
$hasData = $this
39+
->reader
40+
->selectIndex($index)
41+
->hasData();
42+
if (!$hasData) {
43+
throw new EvaluatorException("No index #{$index} at {$reference->getPath()}");
44+
}
45+
} elseif ($this->reader->isObjectSelected()) {
46+
$property = (string) $reference->getKey();
47+
$hasData = $this
48+
->reader
49+
->selectProperty($property)
50+
->hasData();
51+
if (!$hasData) {
52+
throw new EvaluatorException("No property '{$property}' at {$reference->getPath()}");
53+
}
54+
} else {
55+
throw new EvaluatorException("Scalar data at {$reference->getPath()}");
56+
}
57+
return $this;
58+
}
59+
}

src/Evaluator/OperationTest.php

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
namespace Remorhaz\JSONPointer\Evaluator;
4+
5+
use Remorhaz\JSONPointer\Data\SelectableReaderInterface;
6+
use Remorhaz\JSONPointer\Locator\Locator;
7+
use Remorhaz\JSONPointer\Locator\Reference;
8+
9+
class OperationTest extends Operation
10+
{
11+
12+
protected $reader;
13+
14+
15+
public function __construct(Locator $locator, SelectableReaderInterface $reader)
16+
{
17+
parent::__construct($locator);
18+
$this->reader = $reader;
19+
}
20+
21+
22+
public function perform()
23+
{
24+
parent::perform();
25+
if (!$this->isResultSet()) {
26+
$this->setResult(true);
27+
}
28+
return $this;
29+
}
30+
31+
32+
protected function applyReference(Reference $reference)
33+
{
34+
if ($this->reader->isArraySelected()) {
35+
if ($reference->getType() != $reference::TYPE_INDEX) {
36+
return $this->setResult(false);
37+
}
38+
$index = (int) $reference->getKey();
39+
$hasData = $this
40+
->reader
41+
->selectIndex($index)
42+
->hasData();
43+
if (!$hasData) {
44+
return $this->setResult(false);
45+
}
46+
} elseif ($this->reader->isObjectSelected()) {
47+
$property = (string) $reference->getKey();
48+
$hasData = $this
49+
->reader
50+
->selectProperty($property)
51+
->hasData();
52+
if (!$hasData) {
53+
return $this->setResult(false);
54+
}
55+
} else {
56+
return $this->setResult(false);
57+
}
58+
return $this;
59+
}
60+
}

0 commit comments

Comments
 (0)