mirror of
https://github.com/cerbero90/json-parser.git
synced 2025-01-16 20:48:15 +01:00
Leverage PHP 8.1 features
This commit is contained in:
parent
7cb1d906e0
commit
3a0d6fe660
@ -16,7 +16,7 @@ final class ConfigurableDecoder
|
||||
*
|
||||
* @param Config $config
|
||||
*/
|
||||
public function __construct(private Config $config)
|
||||
public function __construct(private readonly Config $config)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -10,21 +10,6 @@ use Throwable;
|
||||
*/
|
||||
final class DecodedValue
|
||||
{
|
||||
/**
|
||||
* Instantiate the class.
|
||||
*
|
||||
* @param mixed $value
|
||||
*/
|
||||
private function __construct(
|
||||
public bool $succeeded,
|
||||
public mixed $value = null,
|
||||
public ?string $error = null,
|
||||
public ?int $code = null,
|
||||
public ?Throwable $exception = null,
|
||||
public ?string $json = null,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a successfully decoded value
|
||||
*
|
||||
@ -47,4 +32,19 @@ final class DecodedValue
|
||||
{
|
||||
return new self(false, null, $e->getMessage(), $e->getCode(), $e, $json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate the class.
|
||||
*
|
||||
* @param mixed $value
|
||||
*/
|
||||
private function __construct(
|
||||
public readonly bool $succeeded,
|
||||
public mixed $value = null,
|
||||
public readonly ?string $error = null,
|
||||
public readonly ?int $code = null,
|
||||
public readonly ?Throwable $exception = null,
|
||||
public readonly ?string $json = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ final class JsonDecoder extends AbstractDecoder
|
||||
* @param bool $decodesToArray
|
||||
* @param int<1, max> $depth
|
||||
*/
|
||||
public function __construct(private bool $decodesToArray = true, private int $depth = 512)
|
||||
public function __construct(private readonly bool $decodesToArray = true, private readonly int $depth = 512)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ final class SimdjsonDecoder extends AbstractDecoder
|
||||
* @param bool $decodesToArray
|
||||
* @param int $depth
|
||||
*/
|
||||
public function __construct(private bool $decodesToArray = true, private int $depth = 512)
|
||||
public function __construct(private readonly bool $decodesToArray = true, private readonly int $depth = 512)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ final class DecodingException extends Exception implements JsonParserException
|
||||
*
|
||||
* @param DecodedValue $decoded
|
||||
*/
|
||||
public function __construct(public DecodedValue $decoded)
|
||||
public function __construct(public readonly DecodedValue $decoded)
|
||||
{
|
||||
parent::__construct('Decoding error: ' . $decoded->error, (int) $decoded->code);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class IntersectingPointersException extends Exception implements JsonParserExcep
|
||||
* @param Pointer $pointer1
|
||||
* @param Pointer $pointer2
|
||||
*/
|
||||
public function __construct(public Pointer $pointer1, public Pointer $pointer2)
|
||||
public function __construct(public readonly Pointer $pointer1, public readonly Pointer $pointer2)
|
||||
{
|
||||
parent::__construct("The pointers [$pointer1] and [$pointer2] are intersecting");
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ final class InvalidPointerException extends Exception implements JsonParserExcep
|
||||
*
|
||||
* @param string $pointer
|
||||
*/
|
||||
public function __construct(public string $pointer)
|
||||
public function __construct(public readonly string $pointer)
|
||||
{
|
||||
parent::__construct("The string [$pointer] is not a valid JSON pointer");
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ final class SyntaxException extends Exception implements JsonParserException
|
||||
*
|
||||
* @param string $value
|
||||
*/
|
||||
public function __construct(public string $value)
|
||||
public function __construct(public readonly string $value)
|
||||
{
|
||||
parent::__construct("Syntax error: unexpected '$value'");
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ final class UnsupportedSourceException extends Exception implements JsonParserEx
|
||||
*
|
||||
* @param mixed $source
|
||||
*/
|
||||
public function __construct(public mixed $source)
|
||||
public function __construct(public readonly mixed $source)
|
||||
{
|
||||
parent::__construct('Unable to load JSON from the provided source');
|
||||
}
|
||||
|
@ -27,21 +27,32 @@ final class JsonParser implements IteratorAggregate
|
||||
*
|
||||
* @var Config
|
||||
*/
|
||||
private Config $config;
|
||||
private readonly Config $config;
|
||||
|
||||
/**
|
||||
* The lexer.
|
||||
*
|
||||
* @var Lexer
|
||||
*/
|
||||
private Lexer $lexer;
|
||||
private readonly Lexer $lexer;
|
||||
|
||||
/**
|
||||
* The parser.
|
||||
*
|
||||
* @var Parser
|
||||
*/
|
||||
private Parser $parser;
|
||||
private readonly Parser $parser;
|
||||
|
||||
/**
|
||||
* Instantiate the class statically
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return self
|
||||
*/
|
||||
public static function parse(mixed $source): self
|
||||
{
|
||||
return new self($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate the class.
|
||||
@ -55,17 +66,6 @@ final class JsonParser implements IteratorAggregate
|
||||
$this->parser = new Parser($this->lexer->getIterator(), $this->config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate the class statically
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return self
|
||||
*/
|
||||
public static function parse(mixed $source): self
|
||||
{
|
||||
return new self($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the lazily iterable JSON
|
||||
*
|
||||
|
@ -22,21 +22,14 @@ final class Pointer implements Stringable
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private array $referenceTokens;
|
||||
public readonly array $referenceTokens;
|
||||
|
||||
/**
|
||||
* The pointer depth.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private int $depth;
|
||||
|
||||
/**
|
||||
* The pointer callback.
|
||||
*
|
||||
* @var Closure
|
||||
*/
|
||||
private ?Closure $callback;
|
||||
public readonly int $depth;
|
||||
|
||||
/**
|
||||
* Whether the pointer was found.
|
||||
@ -52,11 +45,13 @@ final class Pointer implements Stringable
|
||||
* @param bool $isLazy
|
||||
* @param Closure|null $callback
|
||||
*/
|
||||
public function __construct(private string $pointer, private bool $isLazy = false, Closure $callback = null)
|
||||
{
|
||||
public function __construct(
|
||||
private readonly string $pointer,
|
||||
public readonly bool $isLazy = false,
|
||||
private readonly ?Closure $callback = null,
|
||||
) {
|
||||
$this->referenceTokens = $this->toReferenceTokens();
|
||||
$this->depth = count($this->referenceTokens);
|
||||
$this->callback = $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,36 +71,6 @@ final class Pointer implements Stringable
|
||||
return array_slice($referenceTokens, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the pointer is lazy
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLazy(): bool
|
||||
{
|
||||
return $this->isLazy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the reference tokens
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function referenceTokens(): array
|
||||
{
|
||||
return $this->referenceTokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the JSON pointer depth
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function depth(): int
|
||||
{
|
||||
return $this->depth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the pointer callback
|
||||
*
|
||||
|
@ -76,7 +76,7 @@ final class Pointers
|
||||
$originalTree = $tree->original();
|
||||
|
||||
foreach ($this->pointers as $pointer) {
|
||||
if ($pointer->referenceTokens() == $originalTree) {
|
||||
if ($pointer->referenceTokens == $originalTree) {
|
||||
return $this->matching = $pointer;
|
||||
}
|
||||
|
||||
|
@ -13,13 +13,6 @@ use Traversable;
|
||||
*/
|
||||
abstract class Source implements IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* The configuration.
|
||||
*
|
||||
* @var Config
|
||||
*/
|
||||
protected Config $config;
|
||||
|
||||
/**
|
||||
* The cached size of the JSON source.
|
||||
*
|
||||
@ -57,14 +50,15 @@ abstract class Source implements IteratorAggregate
|
||||
abstract protected function calculateSize(): ?int;
|
||||
|
||||
/**
|
||||
* Enforce the factory method to instantiate the class.
|
||||
* Instantiate the class.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @param Config|null $config
|
||||
*/
|
||||
final public function __construct(protected mixed $source, Config $config = null)
|
||||
{
|
||||
$this->config = $config ?: new Config();
|
||||
final public function __construct(
|
||||
protected readonly mixed $source,
|
||||
protected readonly Config $config = new Config(),
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,7 @@ final class Comma extends Token
|
||||
*/
|
||||
public function mutateState(State $state): void
|
||||
{
|
||||
$state->expectsKey = $state->tree()->inObject();
|
||||
$state->expectsKey = $state->tree->inObject();
|
||||
$state->expectedToken = $state->expectsKey ? Tokens::SCALAR_STRING : Tokens::VALUE_ANY;
|
||||
}
|
||||
}
|
||||
|
@ -25,16 +25,14 @@ final class CompoundBegin extends Token
|
||||
*/
|
||||
public function mutateState(State $state): void
|
||||
{
|
||||
$tree = $state->tree();
|
||||
|
||||
if ($this->shouldLazyLoad = $this->shouldLazyLoad && $tree->depth() >= 0) {
|
||||
$state->expectedToken = $tree->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE;
|
||||
if ($this->shouldLazyLoad = $this->shouldLazyLoad && $state->tree->depth() >= 0) {
|
||||
$state->expectedToken = $state->tree->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE;
|
||||
return;
|
||||
}
|
||||
|
||||
$state->expectsKey = $beginsObject = $this->value == '{';
|
||||
$state->expectedToken = $beginsObject ? Tokens::AFTER_OBJECT_BEGIN : Tokens::AFTER_ARRAY_BEGIN;
|
||||
$tree->deepen($beginsObject);
|
||||
$state->tree->deepen($beginsObject);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,9 +18,9 @@ final class CompoundEnd extends Token
|
||||
*/
|
||||
public function mutateState(State $state): void
|
||||
{
|
||||
$state->tree()->emerge();
|
||||
$state->tree->emerge();
|
||||
|
||||
$state->expectedToken = $state->tree()->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE;
|
||||
$state->expectedToken = $state->tree->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,7 @@ final class Constant extends Token
|
||||
*/
|
||||
public function mutateState(State $state): void
|
||||
{
|
||||
$state->expectedToken = $state->tree()->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE;
|
||||
$state->expectedToken = $state->tree->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,7 @@ final class Lexer implements IteratorAggregate
|
||||
*
|
||||
* @var Progress
|
||||
*/
|
||||
private Progress $progress;
|
||||
private readonly Progress $progress;
|
||||
|
||||
/**
|
||||
* The current position.
|
||||
@ -39,7 +39,7 @@ final class Lexer implements IteratorAggregate
|
||||
*
|
||||
* @param Source $source
|
||||
*/
|
||||
public function __construct(private Source $source)
|
||||
public function __construct(private readonly Source $source)
|
||||
{
|
||||
$this->progress = new Progress();
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ final class Parser implements IteratorAggregate
|
||||
*
|
||||
* @var ConfigurableDecoder
|
||||
*/
|
||||
private ConfigurableDecoder $decoder;
|
||||
private readonly ConfigurableDecoder $decoder;
|
||||
|
||||
/**
|
||||
* Whether the parser is fast-forwarding.
|
||||
@ -40,7 +40,7 @@ final class Parser implements IteratorAggregate
|
||||
* @param Generator<int, Token> $tokens
|
||||
* @param Config $config
|
||||
*/
|
||||
public function __construct(private Generator $tokens, private Config $config)
|
||||
public function __construct(private readonly Generator $tokens, private readonly Config $config)
|
||||
{
|
||||
$this->decoder = new ConfigurableDecoder($config);
|
||||
}
|
||||
@ -63,13 +63,13 @@ final class Parser implements IteratorAggregate
|
||||
|
||||
$state->mutateByToken($token);
|
||||
|
||||
if (!$token->endsChunk() || $state->tree()->isDeep()) {
|
||||
if (!$token->endsChunk() || $state->tree->isDeep()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($state->hasBuffer()) {
|
||||
/** @var string|int $key */
|
||||
$key = $this->decoder->decode($state->key());
|
||||
$key = $this->decoder->decode($state->tree->currentKey());
|
||||
$value = $this->decoder->decode($state->value());
|
||||
|
||||
yield $key => $state->callPointer($value, $key);
|
||||
|
@ -31,7 +31,7 @@ final class ScalarString extends Token
|
||||
return;
|
||||
}
|
||||
|
||||
$state->expectedToken = $state->tree()->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE;
|
||||
$state->expectedToken = $state->tree->inObject() ? Tokens::AFTER_OBJECT_VALUE : Tokens::AFTER_ARRAY_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,7 +20,7 @@ final class Tokenizer
|
||||
*
|
||||
* @var array<int, Token>
|
||||
*/
|
||||
private array $tokensMap;
|
||||
private array $tokensMap = [];
|
||||
|
||||
/**
|
||||
* Retrieve the singleton instance
|
||||
|
@ -20,7 +20,7 @@ final class State
|
||||
*
|
||||
* @var Tree
|
||||
*/
|
||||
private Tree $tree;
|
||||
public readonly Tree $tree;
|
||||
|
||||
/**
|
||||
* The JSON buffer.
|
||||
@ -49,7 +49,7 @@ final class State
|
||||
* @param Pointers $pointers
|
||||
* @param Closure $lazyLoad
|
||||
*/
|
||||
public function __construct(private Pointers $pointers, private Closure $lazyLoad)
|
||||
public function __construct(private readonly Pointers $pointers, private readonly Closure $lazyLoad)
|
||||
{
|
||||
$this->tree = new Tree($pointers);
|
||||
}
|
||||
@ -64,16 +64,6 @@ final class State
|
||||
return $this->tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current key of the JSON tree
|
||||
*
|
||||
* @return string|int
|
||||
*/
|
||||
public function key(): string|int
|
||||
{
|
||||
return $this->tree->currentKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the parser can stop parsing
|
||||
*
|
||||
@ -109,7 +99,7 @@ final class State
|
||||
if ($this->tree->isMatched() && ((!$this->expectsKey && $token->isValue()) || $this->tree->isDeep())) {
|
||||
$pointer = $this->pointers->markAsFound();
|
||||
|
||||
if ($token instanceof CompoundBegin && $pointer->isLazy()) {
|
||||
if ($token instanceof CompoundBegin && $pointer->isLazy) {
|
||||
$this->buffer = ($this->lazyLoad)();
|
||||
$token->shouldLazyLoad = true;
|
||||
} else {
|
||||
|
@ -46,7 +46,7 @@ final class Tree
|
||||
*
|
||||
* @param Pointers $pointers
|
||||
*/
|
||||
public function __construct(private Pointers $pointers)
|
||||
public function __construct(private readonly Pointers $pointers)
|
||||
{
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ final class Tree
|
||||
{
|
||||
$pointer = $this->pointers->matching();
|
||||
|
||||
return $pointer == '' ? $this->depth > 0 : $this->depth >= $pointer->depth();
|
||||
return $pointer == '' ? $this->depth > 0 : $this->depth >= $pointer->depth;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,7 +135,7 @@ final class Tree
|
||||
{
|
||||
$pointer = $this->pointers->matching();
|
||||
|
||||
if ($pointer != '' && $this->depth >= $pointer->depth()) {
|
||||
if ($pointer != '' && $this->depth >= $pointer->depth) {
|
||||
return;
|
||||
} elseif ($expectsKey) {
|
||||
$this->traverseKey($token);
|
||||
@ -191,7 +191,7 @@ final class Tree
|
||||
array_splice($this->inObjectByDepth, $offset);
|
||||
}
|
||||
|
||||
$referenceTokens = $this->pointers->matchTree($this)->referenceTokens();
|
||||
$referenceTokens = $this->pointers->matchTree($this)->referenceTokens;
|
||||
$this->wildcarded[$this->depth] = ($referenceTokens[$this->depth] ?? null) == '-' ? '-' : $index;
|
||||
|
||||
if (count($this->wildcarded) > $offset) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user