Update pointer key by reference

This commit is contained in:
Andrea Marco Sartori 2023-03-27 23:03:21 +10:00
parent 4f172a0fc6
commit 7d841f4d77
4 changed files with 33 additions and 8 deletions

View File

@ -113,7 +113,7 @@ final class Pointer implements Stringable
* @param mixed $key
* @return mixed
*/
public function call(mixed $value, mixed $key): mixed
public function call(mixed $value, mixed &$key): mixed
{
if ($this->callback === null) {
return $value;

View File

@ -51,7 +51,7 @@ final class State
*/
public function __construct(private Pointers $pointers, private Closure $lazyLoad)
{
$this->tree = new Tree($this->pointers);
$this->tree = new Tree($pointers);
}
/**
@ -91,7 +91,7 @@ final class State
* @param mixed $key
* @return mixed
*/
public function callPointer(mixed $value, mixed $key): mixed
public function callPointer(mixed $value, mixed &$key): mixed
{
return $this->pointers->matching()->call($value, $key);
}
@ -107,11 +107,15 @@ final class State
$this->tree->traverseToken($token, $this->expectsKey);
if ($this->tree->isMatched() && ((!$this->expectsKey && $token->isValue()) || $this->tree->isDeep())) {
$shouldLazyLoad = $token instanceof CompoundBegin && $this->pointers->matching()->isLazy();
/** @phpstan-ignore-next-line */
$this->buffer = $shouldLazyLoad ? ($this->lazyLoad)() : $this->buffer . $token;
/** @var CompoundBegin $token */
$shouldLazyLoad && $token->shouldLazyLoad = true;
$this->pointers->markAsFound();
if ($token instanceof CompoundBegin && $this->pointers->matching()->isLazy()) {
$this->buffer = ($this->lazyLoad)();
$token->shouldLazyLoad = true;
} else {
/** @phpstan-ignore-next-line */
$this->buffer .= $token;
}
}
$token->mutateState($this);

View File

@ -96,6 +96,23 @@ final class Dataset
yield from self::forSinglePointersWithFixture('pointers/single_pointer_to_array.php');
}
/**
* Retrieve the dataset to test the key update
*
* @return Generator
*/
public static function forKeyUpdate(): Generator
{
$json = fixture('json/complex_object.json');
$pointers = [
'/type' => function ($value, &$key) {
$key = 'foo';
},
];
yield [$json, $pointers, ['foo' => 'donut']];
}
/**
* Retrieve the dataset to test multiple pointers
*

View File

@ -23,6 +23,10 @@ it('eager loads lazy pointers into an array', function (string $json, string $po
expect(JsonParser::parse($json)->lazyPointer($pointer)->toArray())->toBe($expected);
})->with(Dataset::forSinglePointersToArray());
it('can modify key and value of a pointer', function (string $json, array $pointers, array $expected) {
expect(JsonParser::parse($json)->pointers($pointers)->toArray())->toBe($expected);
})->with(Dataset::forKeyUpdate());
it('loads JSON from multiple JSON pointers', function (string $json, array $pointers, array $parsed) {
expect(JsonParser::parse($json)->pointers($pointers))->toPointTo($parsed);
})->with(Dataset::forMultiplePointers());