Skip to content
This repository was archived by the owner on Mar 29, 2024. It is now read-only.

Commit 40cc8a5

Browse files
committed
Add "any" extractor and make it default for []
Vast majority cases of [] usage means that so let's make it shorter
1 parent 928a4f4 commit 40cc8a5

File tree

5 files changed

+115
-9
lines changed

5 files changed

+115
-9
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare(strict_types=1);
2+
3+
/*
4+
* This file is part of the pinepain/js-sandbox PHP library.
5+
*
6+
* Copyright (c) 2016-2017 Bogdan Padalko <[email protected]>
7+
*
8+
* Licensed under the MIT license: http://opensource.org/licenses/MIT
9+
*
10+
* For the full copyright and license information, please view the
11+
* LICENSE file that was distributed with this source or visit
12+
* http://opensource.org/licenses/MIT
13+
*/
14+
15+
16+
namespace Pinepain\JsSandbox\Extractors\Definition;
17+
18+
19+
class RecursiveExtractorDefinition extends AbstractExtractorDefinition implements PlainExtractorDefinitionInterface
20+
{
21+
public function __construct(string $name)
22+
{
23+
parent::__construct($name, $this, [$this]);
24+
}
25+
}

src/Extractors/ExtractorDefinitionBuilder.php

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Pinepain\JsSandbox\Extractors\Definition\ExtractorDefinitionInterface;
2020
use Pinepain\JsSandbox\Extractors\Definition\PlainExtractorDefinition;
2121
use Pinepain\JsSandbox\Extractors\Definition\PlainExtractorDefinitionInterface;
22+
use Pinepain\JsSandbox\Extractors\Definition\RecursiveExtractorDefinition;
2223
use Pinepain\JsSandbox\Extractors\Definition\VariableExtractorDefinition;
2324

2425

@@ -93,7 +94,7 @@ public function build(string $definition): ExtractorDefinitionInterface
9394
* @param int $depth
9495
* @param bool $groups
9596
*
96-
* @return ExtractorDefinitionInterface
97+
* @return null|ExtractorDefinitionInterface
9798
* @throws ExtractorDefinitionBuilderException
9899
*/
99100
protected function buildExtractor(string $name, string $param, string $alt_definitions, int $depth, bool $groups): ExtractorDefinitionInterface
@@ -105,7 +106,7 @@ protected function buildExtractor(string $name, string $param, string $alt_defin
105106
}
106107

107108
if ($name) {
108-
$definition = new PlainExtractorDefinition($name, $next);
109+
$definition = $this->buildPlainExtractor($name, $next);
109110
} else {
110111
$definition = $next;
111112
}
@@ -162,14 +163,19 @@ protected function buildVariableDefinition(PlainExtractorDefinitionInterface $de
162163
*/
163164
protected function buildArrayDefinition(?ExtractorDefinitionInterface $definition, int $depth, bool $groups): ExtractorDefinitionInterface
164165
{
165-
if (!$definition && $groups) {
166-
throw new ExtractorDefinitionBuilderException('Empty group is not allowed');
166+
// special case for blank brackets [] which should be the same as any[]
167+
if (!$definition) {
168+
if ($groups) {
169+
throw new ExtractorDefinitionBuilderException('Empty group is not allowed');
170+
}
171+
172+
$definition = $this->buildPlainExtractor('any');
167173
}
168174

169175
while ($depth) {
170176
$depth--;
171177
// arrayed definition
172-
$definition = new PlainExtractorDefinition('[]', $definition);
178+
$definition = $this->buildPlainExtractor('[]', $definition);
173179
}
174180

175181
return $definition;
@@ -193,4 +199,13 @@ private function hasGroups(array $matches): bool
193199
{
194200
return isset($matches['group']) && '' !== $matches['group'];
195201
}
202+
203+
private function buildPlainExtractor(string $name, ?ExtractorDefinitionInterface $next = null): PlainExtractorDefinitionInterface
204+
{
205+
if ('any' === $name && !$next) {
206+
return new RecursiveExtractorDefinition($name);
207+
}
208+
209+
return new PlainExtractorDefinition($name, $next);
210+
}
196211
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php declare(strict_types=1);
2+
3+
/*
4+
* This file is part of the pinepain/js-sandbox PHP library.
5+
*
6+
* Copyright (c) 2016-2017 Bogdan Padalko <[email protected]>
7+
*
8+
* Licensed under the MIT license: http://opensource.org/licenses/MIT
9+
*
10+
* For the full copyright and license information, please view the
11+
* LICENSE file that was distributed with this source or visit
12+
* http://opensource.org/licenses/MIT
13+
*/
14+
15+
16+
namespace Pinepain\JsSandbox\Extractors\PlainExtractors;
17+
18+
19+
use Pinepain\JsSandbox\Extractors\Definition\PlainExtractorDefinitionInterface;
20+
use Pinepain\JsSandbox\Extractors\ExtractorException;
21+
use Pinepain\JsSandbox\Extractors\ExtractorInterface;
22+
use V8\Context;
23+
use V8\Value;
24+
25+
26+
class AnyExtractor implements PlainExtractorInterface
27+
{
28+
/**
29+
* @var PlainExtractorInterface[]
30+
*/
31+
private $extractors;
32+
33+
public function __construct(PlainExtractorInterface ...$extractors)
34+
{
35+
$this->extractors = $extractors;
36+
}
37+
38+
/**
39+
* {@inheritdoc}
40+
*/
41+
public function extract(Context $context, Value $value, PlainExtractorDefinitionInterface $definition, ExtractorInterface $extractor)
42+
{
43+
foreach ($this->extractors as $plain_extractor) {
44+
try {
45+
return $plain_extractor->extract($context, $value, $definition, $extractor);
46+
} catch (ExtractorException $e) {
47+
//
48+
}
49+
}
50+
51+
throw new ExtractorException('Unable to pick proper extractor for ' . $value->typeOf()->value() . 'type');
52+
}
53+
}

src/Laravel/JsSandboxServiceProvider.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
use Pinepain\JsSandbox\Extractors\ExtractorsCollectionInterface;
3535
use Pinepain\JsSandbox\Extractors\ObjectComponents\ExtractorsObjectStore;
3636
use Pinepain\JsSandbox\Extractors\ObjectComponents\ExtractorsObjectStoreInterface;
37+
use Pinepain\JsSandbox\Extractors\PlainExtractors\AnyExtractor;
3738
use Pinepain\JsSandbox\Extractors\PlainExtractors\ArrayExtractor;
3839
use Pinepain\JsSandbox\Extractors\PlainExtractors\AssocExtractor;
3940
use Pinepain\JsSandbox\Extractors\PlainExtractors\BoolExtractor;
@@ -256,7 +257,7 @@ protected function registerExtractor()
256257

257258
// TODO: register basic extractor
258259

259-
$collection->put('[]', $array = new AssocExtractor());
260+
$collection->put('[]', $assoc = new AssocExtractor());
260261
$collection->put('array', $array = new ArrayExtractor(new AssocExtractor(false)));
261262

262263
$collection->put('raw', $raw = new RawExtractor());
@@ -279,6 +280,7 @@ protected function registerExtractor()
279280
$collection->put('jsonable', $json = new JsonableExtractor());
280281

281282
$collection->put('scalar', $scalar = new ScalarExtractor($string, $number, $bool, $null, $undefined));
283+
$collection->put('any', $any = new AnyExtractor($scalar, $regexp, $datetime, $assoc));
282284

283285
return $collection;
284286
});

tests/Extractors/ExtractorDefinitionBuilderTest.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,20 @@ public function testBuildingFromEmptyGroupShouldThrowException()
5757
* @expectedException \Pinepain\JsSandbox\Extractors\ExtractorDefinitionBuilderException
5858
* @expectedExceptionMessage Unable to parse definition: '()[]'
5959
*/
60-
public function testBuildingEmptyGroupArrayedDefinition()
60+
public function testBuildingEmptyGroupArrayedDefinitionShouldFail()
6161
{
6262
$this->builder->build('()[]');
6363
}
6464

65+
/**
66+
* @expectedException \Pinepain\JsSandbox\Extractors\ExtractorDefinitionBuilderException
67+
* @expectedExceptionMessage Unable to parse definition: '((()))[]'
68+
*/
69+
public function testBuildingEmptyGroupArrayedDefinitionWithNestedGroups()
70+
{
71+
$this->builder->build('((()))[]');
72+
}
73+
6574
public function testBuildingPlainDefinition()
6675
{
6776
$definition = $this->builder->build('test');
@@ -81,7 +90,8 @@ public function testBuildingEmptyArrayDefinition()
8190
$this->assertInstanceOf(PlainExtractorDefinitionInterface::class, $definition);
8291

8392
$this->assertSame('[]', $definition->getName());
84-
$this->assertNull($definition->getNext());
93+
$this->assertInstanceOf(PlainExtractorDefinitionInterface::class, $definition->getNext());
94+
$this->assertSame('any', $definition->getNext()->getName());
8595
$this->assertCount(1, $definition->getVariations());
8696
$this->assertSame($definition, $definition->getVariations()[0]);
8797
}
@@ -100,7 +110,8 @@ public function testBuildingEmptyArrayWithNestedEmptyArrayDefinition()
100110
$next = $definition->getNext();
101111

102112
$this->assertSame('[]', $next->getName());
103-
$this->assertNull($next->getNext());
113+
$this->assertInstanceOf(PlainExtractorDefinitionInterface::class, $next->getNext());
114+
$this->assertSame('any', $next->getNext()->getName());
104115
$this->assertCount(1, $next->getVariations());
105116
$this->assertSame($next, $next->getVariations()[0]);
106117
}

0 commit comments

Comments
 (0)