Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
halaxa committed Aug 26, 2024
1 parent 754d360 commit 860cda2
Show file tree
Hide file tree
Showing 9 changed files with 286 additions and 136 deletions.
126 changes: 29 additions & 97 deletions src/FacadeTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,6 @@

trait FacadeTrait
{
/**
* @var iterable
*/
private $chunks;

/**
* @var string
*/
private $jsonPointer;

/**
* @var ItemDecoder|null
*/
private $jsonDecoder;

/**
* @var Parser
*/
Expand All @@ -35,100 +20,34 @@ trait FacadeTrait
*/
private $debugEnabled;

/**
* @todo Make private when PHP 7 stops being supported
*/
protected abstract function recursive(): bool;
public function isDebugEnabled(): bool
{
return $this->debugEnabled;
}

/**
* @param iterable $bytesIterator
*
* @throws InvalidArgumentException
*/
public function __construct($bytesIterator, array $options = [])
private static function createParser($bytesIterator, ItemsOptions $options, bool $recursive): Parser
{
$options = new ItemsOptions($options);

$this->chunks = $bytesIterator;
$this->jsonPointer = $options['pointer'];
$this->jsonDecoder = $options['decoder'];
$this->debugEnabled = $options['debug'];

if ($this->debugEnabled) {
if ($options['debug']) {
$tokensClass = TokensWithDebugging::class;
} else {
$tokensClass = Tokens::class;
}

$this->parser = new Parser(
return new Parser(
new $tokensClass(
$this->chunks
$bytesIterator
),
$this->jsonPointer,
$this->jsonDecoder ?: new ExtJsonDecoder(),
$this->recursive()
$options['pointer'],
$options['decoder'] ?: new ExtJsonDecoder(),
$recursive
);
}

/**
* @param string $string
*
* @return self
*
* @throws InvalidArgumentException
*/
public static function fromString($string, array $options = [])
{
return new self(new StringChunks($string), $options);
}

/**
* @param string $file
*
* @return self
*
* @throws Exception\InvalidArgumentException
*/
public static function fromFile($file, array $options = [])
{
return new self(new FileChunks($file), $options);
}

/**
* @param resource $stream
*
* @return self
*
* @throws Exception\InvalidArgumentException
*/
public static function fromStream($stream, array $options = [])
{
return new self(new StreamChunks($stream), $options);
}

/**
* @param iterable $iterable
*
* @return self
*
* @throws Exception\InvalidArgumentException
*/
public static function fromIterable($iterable, array $options = [])
{
return new self($iterable, $options);
}

/**
* @return \Generator
*
* @throws Exception\PathNotFoundException
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
return $this->parser->getIterator();
}

/**
* @throws Exception\JsonMachineException
*/
Expand Down Expand Up @@ -159,10 +78,23 @@ public function getMatchedJsonPointer(): string
}

/**
* @return bool
* @param string $string
*/
public function isDebugEnabled()
{
return $this->debugEnabled;
}
abstract public static function fromString($string, array $options = []): self;

/**
* @param string $file
*/
abstract public static function fromFile($file, array $options = []): self;

/**
* @param resource $stream
*/
abstract public static function fromStream($stream, array $options = []): self;

/**
* @param iterable $iterable
*/
abstract public static function fromIterable($iterable, array $options = []): self;

}
65 changes: 63 additions & 2 deletions src/Items.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,76 @@

namespace JsonMachine;

use JsonMachine\Exception\InvalidArgumentException;

/**
* Entry-point facade for JSON Machine.
*/
final class Items implements \IteratorAggregate, PositionAware
{
use FacadeTrait;

protected function recursive(): bool
/**
* @param iterable $bytesIterator
*
* @throws InvalidArgumentException
*/
public function __construct($bytesIterator, array $options = [])
{
$options = new ItemsOptions($options);
$this->debugEnabled = $options['debug'];

$this->parser = $this->createParser($bytesIterator, $options, false);
}

/**
* @param string $string
*
* @throws InvalidArgumentException
*/
public static function fromString($string, array $options = []): self
{
return new self(new StringChunks($string), $options);
}

/**
* @param string $file
*
* @throws Exception\InvalidArgumentException
*/
public static function fromFile($file, array $options = []): self
{
return new self(new FileChunks($file), $options);
}

/**
* @param resource $stream
*
* @throws Exception\InvalidArgumentException
*/
public static function fromStream($stream, array $options = []): self
{
return new self(new StreamChunks($stream), $options);
}

/**
* @param iterable $iterable
*
* @throws Exception\InvalidArgumentException
*/
public static function fromIterable($iterable, array $options = []): self
{
return new self($iterable, $options);
}

/**
* @return \Generator
*
* @throws Exception\PathNotFoundException
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
return false;
return $this->parser->getIterator();
}
}
16 changes: 7 additions & 9 deletions src/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,12 @@ public function getIterator()
)
) {
if ($this->recursive && ($token == '{' || $token == '[')) {
$jsonValue = new NestedIterator(
(new self(
$this->remainingTokens(),
'',
$this->jsonDecoder,
true
))->getIterator()
);
$jsonValue = (new self(
$this->remainingTokens(),
'',
$this->jsonDecoder,
true
))->$this->getIterator();
$token = ' ';
} else {
$jsonValue .= $token;
Expand Down Expand Up @@ -400,7 +398,7 @@ public function getCurrentJsonPointer(): string
*/
public function getMatchedJsonPointer(): string
{
if ($this->matchedJsonPointer === null) {
if ($this->isOutsideGenerator()) {
throw new JsonMachineException(__METHOD__.' must be called inside a loop');
}

Expand Down
114 changes: 111 additions & 3 deletions src/RecursiveItems.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,123 @@

namespace JsonMachine;

use Iterator;
use JsonMachine\Exception\InvalidArgumentException;

/**
* Entry-point facade for recursive iteration.
*/
final class RecursiveItems implements \IteratorAggregate, PositionAware
final class RecursiveItems implements \RecursiveIterator, PositionAware
{
use FacadeTrait;

protected function recursive(): bool
/** @var Parser */
private $parser;

/** @var ItemsOptions */
private $options;

/** @var Iterator */
private $parserIterator;

public function __construct(Parser $parser, ItemsOptions $options)
{
$this->parser = $parser;
$this->options = $options;
$this->debugEnabled = $options['debug'];
}

/**
* @throws InvalidArgumentException
*/
public static function fromString($string, array $options = []): self
{
$options = new ItemsOptions($options);
return new self(
self::createParser(new StringChunks($string), $options, true),
$options
);
}

/**
* @throws InvalidArgumentException
*/
public static function fromFile($file, array $options = []): self
{
return true;
$options = new ItemsOptions($options);
return new self(
self::createParser(new FileChunks($file), $options, true),
$options
);
}

/**
* @throws InvalidArgumentException
*/
public static function fromStream($stream, array $options = []): self
{
$options = new ItemsOptions($options);
return new self(
self::createParser(new StreamChunks($stream), $options, true),
$options
);
}

/**
* @throws InvalidArgumentException
*/
public static function fromIterable($iterable, array $options = []): self
{
$options = new ItemsOptions($options);
return new self(
self::createParser($iterable, $options, true),
$options
);
}

public function current()
{
$current = $this->parserIterator->current();
if ($current instanceof Parser) {
return new self($current, $this->options);
}

return $current;
}

public function next()
{
$this->parserIterator->next();
}

public function key()
{
return $this->parserIterator->key();
}

public function valid(): bool
{
return $this->parserIterator->valid();
}

public function rewind()
{
$this->parserIterator = $this->parser->getIterator();
$this->parserIterator->rewind();
}

public function hasChildren(): bool
{
return $this->current() instanceof self;
}

public function getChildren()
{
$current = $this->current();
if ($current instanceof self) {
return $current;
}

return null;
}
}
Loading

0 comments on commit 860cda2

Please sign in to comment.