mirror of
https://github.com/cerbero90/json-parser.git
synced 2025-01-17 21:18:41 +01:00
Update code to reach PHPStan max level
This commit is contained in:
parent
1a5accca0f
commit
4df6056671
@ -9,17 +9,15 @@ namespace Cerbero\JsonParser\Concerns;
|
|||||||
trait DetectsEndpoints
|
trait DetectsEndpoints
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Determine whether the given string points to an endpoint
|
* Determine whether the given value points to an endpoint
|
||||||
*
|
*
|
||||||
* @param string $string
|
* @param string $value
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isEndpoint(string $string): bool
|
public function isEndpoint(string $value): bool
|
||||||
{
|
{
|
||||||
if (($url = parse_url($string)) === false) {
|
return is_array($url = parse_url($value))
|
||||||
return false;
|
&& in_array($url['scheme'] ?? null, ['http', 'https'])
|
||||||
}
|
&& isset($url['host']);
|
||||||
|
|
||||||
return isset($url['host']) && in_array($url['scheme'] ?? null, ['http', 'https']);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use Closure;
|
|||||||
* The configuration.
|
* The configuration.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Config
|
final class Config
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The JSON decoder.
|
* The JSON decoder.
|
||||||
@ -31,7 +31,7 @@ class Config
|
|||||||
/**
|
/**
|
||||||
* The number of bytes to read in each chunk.
|
* The number of bytes to read in each chunk.
|
||||||
*
|
*
|
||||||
* @var int
|
* @var int<1, max>
|
||||||
*/
|
*/
|
||||||
public int $bytes = 1024 * 8;
|
public int $bytes = 1024 * 8;
|
||||||
|
|
||||||
|
@ -8,14 +8,14 @@ use Cerbero\JsonParser\Config;
|
|||||||
* The configurable decoder.
|
* The configurable decoder.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class CustomDecoder
|
final class ConfigurableDecoder
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Instantiate the class.
|
* Instantiate the class.
|
||||||
*
|
*
|
||||||
* @param Config $config
|
* @param Config $config
|
||||||
*/
|
*/
|
||||||
public function __construct(protected Config $config)
|
public function __construct(private Config $config)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -8,14 +8,14 @@ use JsonException;
|
|||||||
* The decoded value.
|
* The decoded value.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class DecodedValue
|
final class DecodedValue
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Instantiate the class.
|
* Instantiate the class.
|
||||||
*
|
*
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
*/
|
*/
|
||||||
protected function __construct(
|
private function __construct(
|
||||||
public bool $succeeded,
|
public bool $succeeded,
|
||||||
public mixed $value = null,
|
public mixed $value = null,
|
||||||
public ?string $error = null,
|
public ?string $error = null,
|
||||||
|
@ -6,7 +6,7 @@ namespace Cerbero\JsonParser\Exceptions;
|
|||||||
* The exception thrown when a pointer-related error occurs.
|
* The exception thrown when a pointer-related error occurs.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class PointerException extends JsonParserException
|
final class PointerException extends JsonParserException
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Retrieve the exception when the given pointer is invalid
|
* Retrieve the exception when the given pointer is invalid
|
||||||
|
@ -6,7 +6,7 @@ namespace Cerbero\JsonParser\Exceptions;
|
|||||||
* The exception thrown when a source-related error occurs.
|
* The exception thrown when a source-related error occurs.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class SourceException extends JsonParserException
|
final class SourceException extends JsonParserException
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Retrieve the exception when a JSON source is not supported
|
* Retrieve the exception when a JSON source is not supported
|
||||||
|
@ -13,22 +13,23 @@ use Traversable;
|
|||||||
/**
|
/**
|
||||||
* The JSON parser entry-point.
|
* The JSON parser entry-point.
|
||||||
*
|
*
|
||||||
|
* @implements IteratorAggregate<string|int, mixed>
|
||||||
*/
|
*/
|
||||||
class JsonParser implements IteratorAggregate
|
final class JsonParser implements IteratorAggregate
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The configuration.
|
* The configuration.
|
||||||
*
|
*
|
||||||
* @var Config
|
* @var Config
|
||||||
*/
|
*/
|
||||||
protected Config $config;
|
private Config $config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The parser.
|
* The parser.
|
||||||
*
|
*
|
||||||
* @var Parser
|
* @var Parser
|
||||||
*/
|
*/
|
||||||
protected Parser $parser;
|
private Parser $parser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate the class.
|
* Instantiate the class.
|
||||||
@ -38,7 +39,7 @@ class JsonParser implements IteratorAggregate
|
|||||||
public function __construct(mixed $source)
|
public function __construct(mixed $source)
|
||||||
{
|
{
|
||||||
$this->config = new Config();
|
$this->config = new Config();
|
||||||
$this->parser = Parser::for(AnySource::from($source, $this->config));
|
$this->parser = Parser::for(new AnySource($source, $this->config));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,7 +92,7 @@ class JsonParser implements IteratorAggregate
|
|||||||
/**
|
/**
|
||||||
* The number of bytes to read in each chunk
|
* The number of bytes to read in each chunk
|
||||||
*
|
*
|
||||||
* @param int $bytes
|
* @param int<1, max> $bytes
|
||||||
* @return static
|
* @return static
|
||||||
*/
|
*/
|
||||||
public function bytes(int $bytes): static
|
public function bytes(int $bytes): static
|
||||||
|
@ -13,43 +13,44 @@ use Traversable;
|
|||||||
/**
|
/**
|
||||||
* The JSON lexer.
|
* The JSON lexer.
|
||||||
*
|
*
|
||||||
|
* @implements IteratorAggregate<int, Token>
|
||||||
*/
|
*/
|
||||||
class Lexer implements IteratorAggregate
|
final class Lexer implements IteratorAggregate
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The tokenizer.
|
* The tokenizer.
|
||||||
*
|
*
|
||||||
* @var Tokenizer
|
* @var Tokenizer
|
||||||
*/
|
*/
|
||||||
protected Tokenizer $tokenizer;
|
private Tokenizer $tokenizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The buffer to yield.
|
* The buffer to yield.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected string $buffer = '';
|
private string $buffer = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the current character is escaped.
|
* Whether the current character is escaped.
|
||||||
*
|
*
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
protected bool $isEscaping = false;
|
private bool $isEscaping = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the current character belongs to a string.
|
* Whether the current character belongs to a string.
|
||||||
*
|
*
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
protected bool $inString = false;
|
private bool $inString = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate the class.
|
* Instantiate the class.
|
||||||
*
|
*
|
||||||
* @param Source $source
|
* @param Source $source
|
||||||
*/
|
*/
|
||||||
public function __construct(protected Source $source)
|
public function __construct(private Source $source)
|
||||||
{
|
{
|
||||||
$this->tokenizer = new Tokenizer();
|
$this->tokenizer = new Tokenizer();
|
||||||
}
|
}
|
||||||
@ -78,7 +79,7 @@ class Lexer implements IteratorAggregate
|
|||||||
* @param string $character
|
* @param string $character
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function inString(string $character): bool
|
private function inString(string $character): bool
|
||||||
{
|
{
|
||||||
return ($character == '"' && $this->inString && $this->isEscaping)
|
return ($character == '"' && $this->inString && $this->isEscaping)
|
||||||
|| ($character != '"' && $this->inString)
|
|| ($character != '"' && $this->inString)
|
||||||
@ -91,7 +92,7 @@ class Lexer implements IteratorAggregate
|
|||||||
* @param string $character
|
* @param string $character
|
||||||
* @return Generator<int, Token>
|
* @return Generator<int, Token>
|
||||||
*/
|
*/
|
||||||
protected function yieldOrBufferCharacter(string $character): Generator
|
private function yieldOrBufferCharacter(string $character): Generator
|
||||||
{
|
{
|
||||||
if ($this->inString || !isset(Tokens::BOUNDARIES[$character])) {
|
if ($this->inString || !isset(Tokens::BOUNDARIES[$character])) {
|
||||||
$this->buffer .= $character;
|
$this->buffer .= $character;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Cerbero\JsonParser;
|
namespace Cerbero\JsonParser;
|
||||||
|
|
||||||
use Cerbero\JsonParser\Decoders\CustomDecoder;
|
use Cerbero\JsonParser\Decoders\ConfigurableDecoder;
|
||||||
use Cerbero\JsonParser\Sources\Source;
|
use Cerbero\JsonParser\Sources\Source;
|
||||||
use IteratorAggregate;
|
use IteratorAggregate;
|
||||||
use Traversable;
|
use Traversable;
|
||||||
@ -10,22 +10,23 @@ use Traversable;
|
|||||||
/**
|
/**
|
||||||
* The JSON parser.
|
* The JSON parser.
|
||||||
*
|
*
|
||||||
|
* @implements IteratorAggregate<string|int, mixed>
|
||||||
*/
|
*/
|
||||||
class Parser implements IteratorAggregate
|
final class Parser implements IteratorAggregate
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The JSON parsing state.
|
* The JSON parsing state.
|
||||||
*
|
*
|
||||||
* @var State
|
* @var State
|
||||||
*/
|
*/
|
||||||
protected State $state;
|
private State $state;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The decoder handling potential errors.
|
* The decoder handling potential errors.
|
||||||
*
|
*
|
||||||
* @var CustomDecoder
|
* @var ConfigurableDecoder
|
||||||
*/
|
*/
|
||||||
protected CustomDecoder $decoder;
|
private ConfigurableDecoder $decoder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate the class.
|
* Instantiate the class.
|
||||||
@ -33,10 +34,10 @@ class Parser implements IteratorAggregate
|
|||||||
* @param Lexer $lexer
|
* @param Lexer $lexer
|
||||||
* @param Config $config
|
* @param Config $config
|
||||||
*/
|
*/
|
||||||
public function __construct(protected Lexer $lexer, protected Config $config)
|
public function __construct(private Lexer $lexer, private Config $config)
|
||||||
{
|
{
|
||||||
$this->state = new State();
|
$this->state = new State();
|
||||||
$this->decoder = new CustomDecoder($config);
|
$this->decoder = new ConfigurableDecoder($config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,21 +10,21 @@ use Stringable;
|
|||||||
* The JSON pointer.
|
* The JSON pointer.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Pointer implements Stringable
|
final class Pointer implements Stringable
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The reference tokens.
|
* The reference tokens.
|
||||||
*
|
*
|
||||||
* @var string[]
|
* @var string[]
|
||||||
*/
|
*/
|
||||||
protected array $referenceTokens;
|
private array $referenceTokens;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The pointer depth.
|
* The pointer depth.
|
||||||
*
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
protected int $depth;
|
private int $depth;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the pointer was found.
|
* Whether the pointer was found.
|
||||||
@ -38,7 +38,7 @@ class Pointer implements Stringable
|
|||||||
*
|
*
|
||||||
* @param string $pointer
|
* @param string $pointer
|
||||||
*/
|
*/
|
||||||
public function __construct(protected string $pointer)
|
public function __construct(private string $pointer)
|
||||||
{
|
{
|
||||||
$this->referenceTokens = $this->toReferenceTokens();
|
$this->referenceTokens = $this->toReferenceTokens();
|
||||||
$this->depth = count($this->referenceTokens);
|
$this->depth = count($this->referenceTokens);
|
||||||
@ -49,7 +49,7 @@ class Pointer implements Stringable
|
|||||||
*
|
*
|
||||||
* @return string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
protected function toReferenceTokens(): array
|
private function toReferenceTokens(): array
|
||||||
{
|
{
|
||||||
if (preg_match('#^(?:/(?:(?:[^/~])|(?:~[01]))*)*$#', $this->pointer) === 0) {
|
if (preg_match('#^(?:/(?:(?:[^/~])|(?:~[01]))*)*$#', $this->pointer) === 0) {
|
||||||
throw PointerException::invalid($this->pointer);
|
throw PointerException::invalid($this->pointer);
|
||||||
@ -85,20 +85,15 @@ class Pointer implements Stringable
|
|||||||
* Determine whether the reference token at the given depth matches the provided key
|
* Determine whether the reference token at the given depth matches the provided key
|
||||||
*
|
*
|
||||||
* @param int $depth
|
* @param int $depth
|
||||||
* @param mixed $key
|
* @param string|int $key
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function depthMatchesKey(int $depth, mixed $key): bool
|
public function depthMatchesKey(int $depth, string|int $key): bool
|
||||||
{
|
{
|
||||||
if (!isset($this->referenceTokens[$depth])) {
|
$referenceToken = $this->referenceTokens[$depth] ?? null;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->referenceTokens[$depth] === (string) $key) {
|
return $referenceToken === (string) $key
|
||||||
return true;
|
|| (is_int($key) && $referenceToken === '-');
|
||||||
}
|
|
||||||
|
|
||||||
return is_int($key) && $this->referenceTokens[$depth] === '-';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,7 +119,7 @@ class Pointer implements Stringable
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (($firstNest = array_search('-', $this->referenceTokens)) !== false)
|
return is_int($firstNest = array_search('-', $this->referenceTokens))
|
||||||
&& array_slice($this->referenceTokens, 0, $firstNest) === array_slice($tree->original(), 0, $firstNest);
|
&& array_slice($this->referenceTokens, 0, $firstNest) === array_slice($tree->original(), 0, $firstNest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,21 +8,21 @@ use Cerbero\JsonParser\Tree;
|
|||||||
* The JSON pointers collection.
|
* The JSON pointers collection.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Pointers
|
final class Pointers
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The JSON pointers collection.
|
* The JSON pointers collection.
|
||||||
*
|
*
|
||||||
* @var Pointer[]
|
* @var Pointer[]
|
||||||
*/
|
*/
|
||||||
protected array $pointers;
|
private array $pointers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of pointers that were found within the JSON.
|
* The list of pointers that were found within the JSON.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array<string, bool>
|
||||||
*/
|
*/
|
||||||
protected array $found = [];
|
private array $found = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate the class.
|
* Instantiate the class.
|
||||||
|
@ -23,18 +23,18 @@ class AnySource extends Source
|
|||||||
Filename::class,
|
Filename::class,
|
||||||
IterableSource::class,
|
IterableSource::class,
|
||||||
Json::class,
|
Json::class,
|
||||||
|
JsonResource::class,
|
||||||
LaravelClientResponse::class,
|
LaravelClientResponse::class,
|
||||||
Psr7Message::class,
|
Psr7Message::class,
|
||||||
Psr7Stream::class,
|
Psr7Stream::class,
|
||||||
Resource::class,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The matching source.
|
* The matching source.
|
||||||
*
|
*
|
||||||
* @var Source
|
* @var Source|null
|
||||||
*/
|
*/
|
||||||
protected Source $matchingSource;
|
protected ?Source $matchingSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the JSON fragments
|
* Retrieve the JSON fragments
|
||||||
@ -61,7 +61,7 @@ class AnySource extends Source
|
|||||||
protected function sources(): Generator
|
protected function sources(): Generator
|
||||||
{
|
{
|
||||||
foreach ($this->supportedSources as $source) {
|
foreach ($this->supportedSources as $source) {
|
||||||
yield $source::from($this->source, $this->config);
|
yield new $source($this->source, $this->config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ use Traversable;
|
|||||||
/**
|
/**
|
||||||
* The custom source.
|
* The custom source.
|
||||||
*
|
*
|
||||||
|
* @property-read Source $source
|
||||||
*/
|
*/
|
||||||
class CustomSource extends Source
|
class CustomSource extends Source
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,7 @@ use Traversable;
|
|||||||
/**
|
/**
|
||||||
* The endpoint source.
|
* The endpoint source.
|
||||||
*
|
*
|
||||||
|
* @property-read string $source
|
||||||
*/
|
*/
|
||||||
class Endpoint extends Source
|
class Endpoint extends Source
|
||||||
{
|
{
|
||||||
@ -19,9 +20,9 @@ class Endpoint extends Source
|
|||||||
/**
|
/**
|
||||||
* The endpoint response.
|
* The endpoint response.
|
||||||
*
|
*
|
||||||
* @var ResponseInterface
|
* @var ResponseInterface|null
|
||||||
*/
|
*/
|
||||||
protected ResponseInterface $response;
|
protected ?ResponseInterface $response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the JSON fragments
|
* Retrieve the JSON fragments
|
||||||
@ -41,7 +42,7 @@ class Endpoint extends Source
|
|||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return Psr7Message::from($this->response, $this->config);
|
return new Psr7Message($this->response, $this->config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,6 +7,7 @@ use Traversable;
|
|||||||
/**
|
/**
|
||||||
* The filename source.
|
* The filename source.
|
||||||
*
|
*
|
||||||
|
* @property-read string $source
|
||||||
*/
|
*/
|
||||||
class Filename extends Source
|
class Filename extends Source
|
||||||
{
|
{
|
||||||
@ -20,9 +21,9 @@ class Filename extends Source
|
|||||||
$handle = fopen($this->source, 'rb');
|
$handle = fopen($this->source, 'rb');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
yield from Resource::from($handle, $this->config);
|
yield from new JsonResource($handle, $this->config);
|
||||||
} finally {
|
} finally {
|
||||||
fclose($handle);
|
$handle && fclose($handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ use Traversable;
|
|||||||
/**
|
/**
|
||||||
* The iterable source.
|
* The iterable source.
|
||||||
*
|
*
|
||||||
|
* @property-read iterable $source
|
||||||
*/
|
*/
|
||||||
class IterableSource extends Source
|
class IterableSource extends Source
|
||||||
{
|
{
|
||||||
@ -37,6 +38,6 @@ class IterableSource extends Source
|
|||||||
*/
|
*/
|
||||||
protected function calculateSize(): ?int
|
protected function calculateSize(): ?int
|
||||||
{
|
{
|
||||||
return iterator_count(clone $this->source);
|
return is_array($this->source) ? count($this->source) : iterator_count(clone $this->source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ use Traversable;
|
|||||||
/**
|
/**
|
||||||
* The JSON source.
|
* The JSON source.
|
||||||
*
|
*
|
||||||
|
* @property-read string $source
|
||||||
*/
|
*/
|
||||||
class Json extends Source
|
class Json extends Source
|
||||||
{
|
{
|
||||||
|
@ -7,8 +7,9 @@ use Traversable;
|
|||||||
/**
|
/**
|
||||||
* The resource source.
|
* The resource source.
|
||||||
*
|
*
|
||||||
|
* @property-read resource $source
|
||||||
*/
|
*/
|
||||||
class Resource extends Source
|
class JsonResource extends Source
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Retrieve the JSON fragments
|
* Retrieve the JSON fragments
|
||||||
@ -18,7 +19,9 @@ class Resource extends Source
|
|||||||
public function getIterator(): Traversable
|
public function getIterator(): Traversable
|
||||||
{
|
{
|
||||||
while (!feof($this->source)) {
|
while (!feof($this->source)) {
|
||||||
yield fread($this->source, $this->config->bytes);
|
if (is_string($chunk = fread($this->source, $this->config->bytes))) {
|
||||||
|
yield $chunk;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +32,7 @@ class Resource extends Source
|
|||||||
*/
|
*/
|
||||||
public function matches(): bool
|
public function matches(): bool
|
||||||
{
|
{
|
||||||
return is_resource($this->source) || get_resource_type($this->source) == 'stream';
|
return is_resource($this->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
@ -8,6 +8,7 @@ use Traversable;
|
|||||||
/**
|
/**
|
||||||
* The Laravel client response source.
|
* The Laravel client response source.
|
||||||
*
|
*
|
||||||
|
* @property-read Response $source
|
||||||
*/
|
*/
|
||||||
class LaravelClientResponse extends Source
|
class LaravelClientResponse extends Source
|
||||||
{
|
{
|
||||||
@ -18,7 +19,7 @@ class LaravelClientResponse extends Source
|
|||||||
*/
|
*/
|
||||||
public function getIterator(): Traversable
|
public function getIterator(): Traversable
|
||||||
{
|
{
|
||||||
return Psr7Message::from($this->source->toPsrResponse(), $this->config);
|
return new Psr7Message($this->source->toPsrResponse(), $this->config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,6 +8,7 @@ use Traversable;
|
|||||||
/**
|
/**
|
||||||
* The PSR-7 message source.
|
* The PSR-7 message source.
|
||||||
*
|
*
|
||||||
|
* @property-read MessageInterface $source
|
||||||
*/
|
*/
|
||||||
class Psr7Message extends Source
|
class Psr7Message extends Source
|
||||||
{
|
{
|
||||||
@ -18,7 +19,7 @@ class Psr7Message extends Source
|
|||||||
*/
|
*/
|
||||||
public function getIterator(): Traversable
|
public function getIterator(): Traversable
|
||||||
{
|
{
|
||||||
return Psr7Stream::from($this->source->getBody(), $this->config);
|
return new Psr7Stream($this->source->getBody(), $this->config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,6 +8,7 @@ use Traversable;
|
|||||||
/**
|
/**
|
||||||
* The PSR-7 stream source.
|
* The PSR-7 stream source.
|
||||||
*
|
*
|
||||||
|
* @property-read StreamInterface $source
|
||||||
*/
|
*/
|
||||||
class Psr7Stream extends Source
|
class Psr7Stream extends Source
|
||||||
{
|
{
|
||||||
@ -26,7 +27,7 @@ class Psr7Stream extends Source
|
|||||||
StreamWrapper::NAME => ['stream' => $this->source],
|
StreamWrapper::NAME => ['stream' => $this->source],
|
||||||
]));
|
]));
|
||||||
|
|
||||||
return Resource::from($stream, $this->config);
|
return new JsonResource($stream, $this->config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,6 +9,7 @@ use Traversable;
|
|||||||
/**
|
/**
|
||||||
* The JSON source.
|
* The JSON source.
|
||||||
*
|
*
|
||||||
|
* @implements IteratorAggregate<int, string>
|
||||||
*/
|
*/
|
||||||
abstract class Source implements IteratorAggregate
|
abstract class Source implements IteratorAggregate
|
||||||
{
|
{
|
||||||
@ -17,7 +18,7 @@ abstract class Source implements IteratorAggregate
|
|||||||
*
|
*
|
||||||
* @var int|null
|
* @var int|null
|
||||||
*/
|
*/
|
||||||
protected int $size;
|
protected ?int $size;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the JSON fragments
|
* Retrieve the JSON fragments
|
||||||
@ -46,22 +47,10 @@ abstract class Source implements IteratorAggregate
|
|||||||
* @param mixed $source
|
* @param mixed $source
|
||||||
* @param Config $config
|
* @param Config $config
|
||||||
*/
|
*/
|
||||||
protected function __construct(protected mixed $source, protected Config $config)
|
final public function __construct(protected mixed $source, protected Config $config)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiate the class statically
|
|
||||||
*
|
|
||||||
* @param mixed $source
|
|
||||||
* @param Config $config
|
|
||||||
* @return static
|
|
||||||
*/
|
|
||||||
public static function from(mixed $source, Config $config): static
|
|
||||||
{
|
|
||||||
return new static($source, $config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the underlying configuration
|
* Retrieve the underlying configuration
|
||||||
*
|
*
|
||||||
|
@ -9,7 +9,7 @@ use Psr\Http\Message\StreamInterface;
|
|||||||
*
|
*
|
||||||
* @phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
|
* @phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
|
||||||
*/
|
*/
|
||||||
class StreamWrapper
|
final class StreamWrapper
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The name of the stream wrapper.
|
* The name of the stream wrapper.
|
||||||
@ -23,14 +23,14 @@ class StreamWrapper
|
|||||||
*
|
*
|
||||||
* @var resource
|
* @var resource
|
||||||
*/
|
*/
|
||||||
public $context;
|
public mixed $context;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The PSR-7 stream.
|
* The PSR-7 stream.
|
||||||
*
|
*
|
||||||
* @var StreamInterface
|
* @var StreamInterface
|
||||||
*/
|
*/
|
||||||
protected $stream;
|
private $stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the stream
|
* Open the stream
|
||||||
|
@ -10,35 +10,35 @@ use Cerbero\JsonParser\Tokens\Token;
|
|||||||
* The JSON parsing state.
|
* The JSON parsing state.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class State
|
final class State
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The JSON tree.
|
* The JSON tree.
|
||||||
*
|
*
|
||||||
* @var Tree
|
* @var Tree
|
||||||
*/
|
*/
|
||||||
protected Tree $tree;
|
private Tree $tree;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The JSON pointers.
|
* The JSON pointers.
|
||||||
*
|
*
|
||||||
* @var Pointers
|
* @var Pointers
|
||||||
*/
|
*/
|
||||||
protected Pointers $pointers;
|
private Pointers $pointers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The JSON pointer matching the tree.
|
* The JSON pointer matching the tree.
|
||||||
*
|
*
|
||||||
* @var Pointer
|
* @var Pointer
|
||||||
*/
|
*/
|
||||||
protected Pointer $pointer;
|
private Pointer $pointer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The JSON buffer.
|
* The JSON buffer.
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected string $buffer = '';
|
private string $buffer = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether an object key is expected.
|
* Whether an object key is expected.
|
||||||
@ -81,9 +81,9 @@ class State
|
|||||||
/**
|
/**
|
||||||
* Retrieve the current key of the JSON tree
|
* Retrieve the current key of the JSON tree
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string|int
|
||||||
*/
|
*/
|
||||||
public function key(): string
|
public function key(): string|int
|
||||||
{
|
{
|
||||||
return $this->tree->currentKey();
|
return $this->tree->currentKey();
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ class State
|
|||||||
* @param Token $token
|
* @param Token $token
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function bufferToken(Token $token): void
|
private function bufferToken(Token $token): void
|
||||||
{
|
{
|
||||||
$shouldBuffer = $this->tree->depth() >= 0
|
$shouldBuffer = $this->tree->depth() >= 0
|
||||||
&& $this->pointer->matchesTree($this->tree)
|
&& $this->pointer->matchesTree($this->tree)
|
||||||
|
@ -8,7 +8,7 @@ use Cerbero\JsonParser\State;
|
|||||||
* The comma token.
|
* The comma token.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Comma extends Token
|
final class Comma extends Token
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Retrieve the token type
|
* Retrieve the token type
|
||||||
@ -28,8 +28,6 @@ class Comma extends Token
|
|||||||
*/
|
*/
|
||||||
public function mutateState(State $state): void
|
public function mutateState(State $state): void
|
||||||
{
|
{
|
||||||
if ($state->inObject()) {
|
$state->expectsKey = $state->inObject();
|
||||||
$state->expectsKey = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ use Cerbero\JsonParser\State;
|
|||||||
* The token that begins compound data (JSON arrays or objects).
|
* The token that begins compound data (JSON arrays or objects).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class CompoundBegin extends Token
|
final class CompoundBegin extends Token
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Retrieve the token type
|
* Retrieve the token type
|
||||||
@ -30,8 +30,6 @@ class CompoundBegin extends Token
|
|||||||
{
|
{
|
||||||
$state->tree()->deepen();
|
$state->tree()->deepen();
|
||||||
|
|
||||||
if ($this->value == '{') {
|
$state->expectsKey = $this->value == '{';
|
||||||
$state->expectsKey = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ use Cerbero\JsonParser\State;
|
|||||||
* The token that ends compound data (JSON arrays or objects).
|
* The token that ends compound data (JSON arrays or objects).
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class CompoundEnd extends Token
|
final class CompoundEnd extends Token
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Retrieve the token type
|
* Retrieve the token type
|
||||||
@ -29,10 +29,6 @@ class CompoundEnd extends Token
|
|||||||
public function mutateState(State $state): void
|
public function mutateState(State $state): void
|
||||||
{
|
{
|
||||||
$state->tree()->emerge();
|
$state->tree()->emerge();
|
||||||
|
|
||||||
if ($this->value == '}') {
|
|
||||||
$state->expectsKey = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,7 +6,7 @@ namespace Cerbero\JsonParser\Tokens;
|
|||||||
* The constant token, includes colons for convenience.
|
* The constant token, includes colons for convenience.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Constant extends Token
|
final class Constant extends Token
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Retrieve the token type
|
* Retrieve the token type
|
||||||
|
@ -8,14 +8,14 @@ use Cerbero\JsonParser\State;
|
|||||||
* The scalar string token.
|
* The scalar string token.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ScalarString extends Token
|
final class ScalarString extends Token
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Whether this token is an object key.
|
* Whether this token is an object key.
|
||||||
*
|
*
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
protected bool $isKey = false;
|
private bool $isKey = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the token type
|
* Retrieve the token type
|
||||||
|
@ -6,14 +6,14 @@ namespace Cerbero\JsonParser\Tokens;
|
|||||||
* The tokenizer.
|
* The tokenizer.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Tokenizer
|
final class Tokenizer
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The map of token instances by type.
|
* The map of token instances by type.
|
||||||
*
|
*
|
||||||
* @var array<int, Token>
|
* @var array<int, Token>
|
||||||
*/
|
*/
|
||||||
protected static array $tokensMap;
|
private static array $tokensMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiate the class.
|
* Instantiate the class.
|
||||||
@ -29,7 +29,7 @@ class Tokenizer
|
|||||||
*
|
*
|
||||||
* @return array<int, Token>
|
* @return array<int, Token>
|
||||||
*/
|
*/
|
||||||
protected function hydrateTokensMap(): array
|
private function hydrateTokensMap(): array
|
||||||
{
|
{
|
||||||
$map = $instances = [];
|
$map = $instances = [];
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ namespace Cerbero\JsonParser\Tokens;
|
|||||||
* The tokens related information.
|
* The tokens related information.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Tokens
|
final class Tokens
|
||||||
{
|
{
|
||||||
public const SCALAR_CONST = 1 << 0;
|
public const SCALAR_CONST = 1 << 0;
|
||||||
public const SCALAR_STRING = 1 << 1;
|
public const SCALAR_STRING = 1 << 1;
|
||||||
@ -35,7 +35,7 @@ class Tokens
|
|||||||
/**
|
/**
|
||||||
* The token types.
|
* The token types.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array<string|int, int>
|
||||||
*/
|
*/
|
||||||
public const TYPES = [
|
public const TYPES = [
|
||||||
'n' => self::SCALAR_CONST,
|
'n' => self::SCALAR_CONST,
|
||||||
@ -64,7 +64,7 @@ class Tokens
|
|||||||
/**
|
/**
|
||||||
* The token boundaries.
|
* The token boundaries.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array<string, bool>
|
||||||
*/
|
*/
|
||||||
public const BOUNDARIES = [
|
public const BOUNDARIES = [
|
||||||
"\xEF" => true,
|
"\xEF" => true,
|
||||||
@ -85,7 +85,7 @@ class Tokens
|
|||||||
/**
|
/**
|
||||||
* The structural boundaries.
|
* The structural boundaries.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array<string, bool>
|
||||||
*/
|
*/
|
||||||
public const DELIMITERS = [
|
public const DELIMITERS = [
|
||||||
'{' => true,
|
'{' => true,
|
||||||
|
12
src/Tree.php
12
src/Tree.php
@ -2,34 +2,32 @@
|
|||||||
|
|
||||||
namespace Cerbero\JsonParser;
|
namespace Cerbero\JsonParser;
|
||||||
|
|
||||||
use Cerbero\JsonParser\Pointers\Pointer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The JSON tree.
|
* The JSON tree.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Tree
|
final class Tree
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The original JSON tree.
|
* The original JSON tree.
|
||||||
*
|
*
|
||||||
* @var array<int, string|int>
|
* @var array<int, string|int>
|
||||||
*/
|
*/
|
||||||
protected array $original = [];
|
private array $original = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The wildcarded JSON tree.
|
* The wildcarded JSON tree.
|
||||||
*
|
*
|
||||||
* @var array<int, string|int>
|
* @var array<int, string|int>
|
||||||
*/
|
*/
|
||||||
protected array $wildcarded = [];
|
private array $wildcarded = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The JSON tree depth.
|
* The JSON tree depth.
|
||||||
*
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
protected int $depth = -1;
|
private int $depth = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the original JSON tree
|
* Retrieve the original JSON tree
|
||||||
@ -102,7 +100,7 @@ class Tree
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function trim(): void
|
private function trim(): void
|
||||||
{
|
{
|
||||||
array_splice($this->original, $this->depth + 1);
|
array_splice($this->original, $this->depth + 1);
|
||||||
array_splice($this->wildcarded, $this->depth + 1);
|
array_splice($this->wildcarded, $this->depth + 1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user