Skip to content

Commit 699cb70

Browse files
committed
Data cursor advancers implemented to simplify reference evaluators
1 parent d871c82 commit 699cb70

25 files changed

+379
-297
lines changed

src/Pointer/Evaluate/Advancer.php

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<?php
2+
3+
namespace Remorhaz\JSONPointer\Pointer\Evaluate;
4+
5+
use Remorhaz\JSONPointer\Locator\Reference;
6+
7+
abstract class Advancer
8+
{
9+
10+
11+
protected $dataCursor;
12+
13+
protected $isDataCursorSet = false;
14+
15+
protected $newDataCursor;
16+
17+
protected $isNewDataCursorSet = false;
18+
19+
/**
20+
* @var Reference|null
21+
*/
22+
protected $reference;
23+
24+
25+
protected function __construct()
26+
{
27+
}
28+
29+
30+
/**
31+
* @return bool
32+
*/
33+
abstract public function canAdvance();
34+
35+
/**
36+
* @return $this
37+
*/
38+
abstract public function advance();
39+
40+
41+
/**
42+
* @param mixed $data
43+
* @return $this
44+
*/
45+
abstract public function write($data);
46+
47+
48+
public static function factory()
49+
{
50+
return new static();
51+
}
52+
53+
54+
public function setDataCursor(&$dataCursor)
55+
{
56+
$this->dataCursor = &$dataCursor;
57+
$this->isDataCursorSet = true;
58+
return $this;
59+
}
60+
61+
62+
protected function &getDataCursor()
63+
{
64+
if (!$this->isDataCursorSet) {
65+
throw new LogicException("Data cursor is not set in advancer object");
66+
}
67+
return $this->dataCursor;
68+
}
69+
70+
71+
protected function setNewDataCursor(&$dataCursor)
72+
{
73+
$this->newDataCursor = &$dataCursor;
74+
$this->isNewDataCursorSet = true;
75+
return $this;
76+
}
77+
78+
79+
public function &getNewDataCursor()
80+
{
81+
if (!$this->isNewDataCursorSet) {
82+
throw new LogicException("Data cursor is not set in advancer object");
83+
}
84+
return $this->newDataCursor;
85+
}
86+
87+
88+
public function setReference(Reference $reference)
89+
{
90+
$this->reference = $reference;
91+
return $this;
92+
}
93+
94+
95+
protected function getReference()
96+
{
97+
if (null === $this->reference) {
98+
throw new LogicException("Reference is not set in advancer object");
99+
}
100+
return $this->reference;
101+
}
102+
103+
104+
public function getValue()
105+
{
106+
return $this
107+
->getReference()
108+
->getValue();
109+
}
110+
111+
112+
public function getValueDescription()
113+
{
114+
return "'{$this->getValue()}'";
115+
}
116+
}
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Remorhaz\JSONPointer\Pointer\Evaluate;
4+
5+
class AdvancerNewIndex extends Advancer
6+
{
7+
8+
9+
public function canAdvance()
10+
{
11+
return false;
12+
}
13+
14+
15+
public function advance()
16+
{
17+
throw new LogicException("New index is not advanceable");
18+
}
19+
20+
21+
public function write($data)
22+
{
23+
$this->dataCursor[] = $data;
24+
return $this;
25+
}
26+
27+
28+
public function getValue()
29+
{
30+
throw new LogicException("Next index cannot have advanceable value");
31+
}
32+
33+
34+
public function getValueDescription()
35+
{
36+
return "'-'";
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Remorhaz\JSONPointer\Pointer\Evaluate;
4+
5+
class AdvancerNonNumericIndex extends Advancer
6+
{
7+
8+
9+
public function canAdvance()
10+
{
11+
return array_key_exists($this->getValue(), $this->getDataCursor());
12+
}
13+
14+
15+
public function advance()
16+
{
17+
return $this->setNewDataCursor($this->dataCursor[$this->getValue()]);
18+
}
19+
20+
21+
public function write($data)
22+
{
23+
$this->dataCursor[$this->getValue()] = $data;
24+
return $this;
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Remorhaz\JSONPointer\Pointer\Evaluate;
4+
5+
class AdvancerNumericIndex extends AdvancerNonNumericIndex
6+
{
7+
8+
9+
public function getValue()
10+
{
11+
return (int) parent::getValue();
12+
}
13+
14+
15+
public function getValueDescription()
16+
{
17+
return "{$this->getValue()}";
18+
}
19+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Remorhaz\JSONPointer\Pointer\Evaluate;
4+
5+
class AdvancerProperty extends Advancer
6+
{
7+
8+
9+
public function canAdvance()
10+
{
11+
return property_exists($this->getDataCursor(), $this->getValue());
12+
}
13+
14+
15+
public function advance()
16+
{
17+
return $this->setNewDataCursor($this->dataCursor->{$this->getValue()});
18+
}
19+
20+
21+
public function write($data)
22+
{
23+
$this->dataCursor->{$this->getValue()} = $data;
24+
return $this;
25+
}
26+
}

src/Pointer/Evaluate/LocatorWrite.php

+2-4
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,11 @@ protected function processCursor()
5858

5959
protected function setupReferenceEvaluate(Reference $reference)
6060
{
61-
/** @var ReferenceWrite $referenceEvaluate */
6261
$referenceEvaluate = parent::setupReferenceEvaluate($reference)
6362
->getReferenceEvaluate();
64-
if (!($referenceEvaluate instanceof ReferenceWrite)) {
65-
throw new LogicException("Invalid write reference evaluator");
63+
if ($referenceEvaluate instanceof ReferenceWrite) {
64+
$referenceEvaluate->setValue($this->getValue());
6665
}
67-
$referenceEvaluate->setValue($this->getValue());
6866
return $this;
6967
}
7068

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace Remorhaz\JSONPointer\Pointer\Evaluate;
4+
5+
abstract class ReferenceAdvanceable extends ReferenceEvaluate
6+
{
7+
8+
/**
9+
* @var Advancer|null
10+
*/
11+
protected $advanceCursor;
12+
13+
14+
/**
15+
* @return Advancer
16+
*/
17+
abstract protected function createAdvancer();
18+
19+
abstract protected function performNonExisting();
20+
21+
/**
22+
* @return Advancer
23+
*/
24+
protected function getAdvancer()
25+
{
26+
if (null === $this->advanceCursor) {
27+
$this->advanceCursor = $this
28+
->createAdvancer()
29+
->setReference($this->getReference())
30+
->setDataCursor($this->getDataCursor());
31+
}
32+
return $this->advanceCursor;
33+
}
34+
35+
36+
/**
37+
* Performs reference evaluation.
38+
*
39+
* @return $this
40+
*/
41+
public function perform()
42+
{
43+
$canAdvance = $this
44+
->getAdvancer()
45+
->canAdvance();
46+
if ($canAdvance) {
47+
$dataCursor = &$this
48+
->getAdvancer()
49+
->advance()
50+
->getNewDataCursor();
51+
return $this->setDataCursor($dataCursor);
52+
}
53+
return $this->performNonExisting();
54+
}
55+
}

src/Pointer/Evaluate/ReferenceEvaluate.php

+8-19
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ abstract class ReferenceEvaluate
3333

3434
protected $isResultSet;
3535

36-
abstract protected function doesExist();
3736

38-
abstract protected function performExisting();
39-
40-
abstract protected function performNonExisting();
37+
/**
38+
* Performs reference evaluation.
39+
*
40+
* @return $this
41+
*/
42+
abstract public function perform();
4143

4244

4345
/**
@@ -101,8 +103,8 @@ public function &getDataCursor()
101103
}
102104
return $this->dataCursor;
103105
}
104-
105-
106+
107+
106108
public function isResultSet()
107109
{
108110
return $this->isResultSet;
@@ -136,17 +138,4 @@ public function &getResult()
136138
}
137139
return $this->result;
138140
}
139-
140-
141-
/**
142-
* Performs reference evaluation.
143-
*
144-
* @return $this
145-
*/
146-
public function perform()
147-
{
148-
return $this->doesExist()
149-
? $this->performExisting()
150-
: $this->performNonExisting();
151-
}
152141
}

src/Pointer/Evaluate/ReferenceReadAllowedNonNumericIndex.php

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

33
namespace Remorhaz\JSONPointer\Pointer\Evaluate;
44

5-
class ReferenceReadAllowedNonNumericIndex extends ReferenceEvaluate
5+
class ReferenceReadAllowedNonNumericIndex extends ReferenceAdvanceable
66
{
77

88

9-
protected function doesExist()
9+
protected function createAdvancer()
1010
{
11-
return array_key_exists($this->getIndex(), $this->getDataCursor());
12-
}
13-
14-
15-
protected function performExisting()
16-
{
17-
$this->dataCursor = &$this->dataCursor[$this->getIndex()];
18-
return $this;
11+
return AdvancerNonNumericIndex::factory();
1912
}
2013

2114

2215
protected function performNonExisting()
2316
{
24-
throw new EvaluateException("No index '{$this->getIndex()}' in array");
25-
}
26-
27-
28-
protected function getIndex()
29-
{
30-
return $this
31-
->getReference()
32-
->getValue();
17+
$indexDescription = $this
18+
->getAdvancer()
19+
->getValueDescription();
20+
throw new EvaluateException("No index {$indexDescription} in array");
3321
}
3422
}

0 commit comments

Comments
 (0)