Skip to content

Commit

Permalink
Added a way to add a reason to filtering plugin rejects or drops
Browse files Browse the repository at this point in the history
  • Loading branch information
sebprt committed Jun 25, 2024
1 parent 354388c commit ff51a50
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 112 deletions.
72 changes: 2 additions & 70 deletions src/Plugin/Filtering/Builder/Drop.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ final class Drop implements StepBuilderInterface
/** @var list<?Node\Expr> */
private array $exclusions = [];

public function __construct()
{
}

public function withLogger(Node\Expr $logger): self
{
$this->logger = $logger;
Expand All @@ -41,55 +37,13 @@ public function withState(Node\Expr $state): self
return $this;
}

public function withExclusions(Node\Expr ...$exclusions): self
public function withExclusions(Node ...$exclusions): self
{
array_push($this->exclusions, ...$exclusions);

return $this;
}

private function buildExclusions(Node\Expr ...$exclusions): Node\Expr
{
if (\count($exclusions) > 3) {
$length = \count($exclusions);
$middle = (int) floor($length / 2);
$left = \array_slice($exclusions, 0, $middle);
$right = \array_slice($exclusions, $middle, $length);

return new Node\Expr\BinaryOp\BooleanAnd(
$this->buildExclusions(...$left),
$this->buildExclusions(...$right),
);
}

if (\count($exclusions) > 2) {
$right = array_shift($exclusions);

return new Node\Expr\BinaryOp\BooleanAnd(
$this->buildExclusions(...$exclusions),
$right,
);
}

if (\count($exclusions) > 1) {
$left = array_pop($exclusions);
$right = array_pop($exclusions);

return new Node\Expr\BinaryOp\BooleanAnd(
$left,
$right,
);
}

if (\count($exclusions) > 0) {
return array_pop($exclusions);
}

return new Node\Expr\ConstFetch(
new Node\Name('false'),
);
}

public function getNode(): Node
{
return new Node\Expr\New_(
Expand All @@ -113,24 +67,7 @@ class: new Node\Stmt\Class_(null, [
new Node\Name('true'),
),
[
new Node\Stmt\If_(
$this->buildExclusions(...$this->exclusions),
[
'stmts' => [
new Node\Stmt\Expression(
new Node\Expr\Assign(
new Node\Expr\Variable('input'),
new Node\Expr\Yield_(
new Node\Expr\New_(
new Node\Name\FullyQualified('Kiboko\\Component\\Bucket\\RejectionResultBucket'),
),
),
),
),
new Node\Stmt\Continue_(),
],
]
),
...$this->exclusions,
new Node\Stmt\Expression(
new Node\Expr\Assign(
new Node\Expr\Variable('input'),
Expand All @@ -146,11 +83,6 @@ class: new Node\Stmt\Class_(null, [
),
],
),
new Node\Stmt\Expression(
new Node\Expr\Yield_(
new Node\Expr\Variable('input')
),
),
])
->getNode(),
],
Expand Down
28 changes: 12 additions & 16 deletions src/Plugin/Filtering/Builder/ExclusionsBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@

namespace Kiboko\Component\Satellite\Plugin\Filtering\Builder;

use Kiboko\Component\Bucket\RejectionResultBucket;
use Kiboko\Component\Bucket\RejectionWithReasonResultBucket;
use PhpParser\Builder;
use PhpParser\Node;

final class ExclusionsBuilder implements Builder
final class ExclusionsBuilder
{
/** @var list<list<Node\Expr>> */
private array $exclusions = [];

public function withCondition(Node\Expr $condition, ?Node\Expr $reason = null):self
public function withCondition(Node\Expr $condition, ?Node\Expr $reason): self
{
$this->exclusions[] = [
'condition' => $condition,
Expand All @@ -24,11 +21,10 @@ public function withCondition(Node\Expr $condition, ?Node\Expr $reason = null):s
return $this;
}

public function getNode(): Node
public function build(): \Generator
{
$statements = [];
foreach ($this->exclusions as $exclusion) {
$statements[] = new Node\Stmt\If_(
yield new Node\Stmt\If_(
$exclusion['condition'],

Check failure on line 28 in src/Plugin/Filtering/Builder/ExclusionsBuilder.php

View workflow job for this annotation

GitHub Actions / phpstan

Offset 'condition' does not exist on array<int, PhpParser\Node\Expr>.
[
'stmts' => [
Expand All @@ -37,13 +33,15 @@ public function getNode(): Node
new Node\Expr\Variable('input'),
new Node\Expr\Yield_(
new Node\Expr\New_(
\array_key_exists('reason', $exclusion) ? new Node\Name\FullyQualified(RejectionWithReasonResultBucket::class) : new Node\Name\FullyQualified(RejectionResultBucket::class),
new Node\Name\FullyQualified('Kiboko\\Component\\Bucket\\RejectionResultBucket'),
[
new Node\Arg(new Node\Expr\Variable('input')),
\array_key_exists('reason', $exclusion) ? new Node\Arg($exclusion['reason']) : new Node\Arg(
new Node\Expr\ConstFetch(
new Node\Name(null)
),
new Node\Arg(
value: $exclusion['reason'],

Check failure on line 39 in src/Plugin/Filtering/Builder/ExclusionsBuilder.php

View workflow job for this annotation

GitHub Actions / phpstan

Offset 'reason' does not exist on array<int, PhpParser\Node\Expr>.
name: new Node\Identifier('reason')
),
new Node\Arg(
value: new Node\Expr\Variable('input'),
name: new Node\Identifier('values')
),
]
),
Expand All @@ -55,7 +53,5 @@ public function getNode(): Node
]
);
}

return new Node;
}
}
17 changes: 5 additions & 12 deletions src/Plugin/Filtering/Builder/Reject.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@

namespace Kiboko\Component\Satellite\Plugin\Filtering\Builder;

use Kiboko\Component\Bucket\AcceptanceResultBucket;
use Kiboko\Component\Bucket\RejectionResultBucket;
use Kiboko\Component\Bucket\RejectionWithReasonResultBucket;
use Kiboko\Contract\Configurator\StepBuilderInterface;
use PhpParser\Builder;
use PhpParser\Node;
Expand All @@ -16,7 +13,8 @@ final class Reject implements StepBuilderInterface
private ?Node\Expr $logger = null;
private ?Node\Expr $rejection = null;
private ?Node\Expr $state = null;
private ?ExclusionsBuilder $exclusions = null;
/** @var list<?Node\Expr> */
private array $exclusions = [];

public function withLogger(Node\Expr $logger): self
{
Expand All @@ -39,9 +37,9 @@ public function withState(Node\Expr $state): self
return $this;
}

public function withExclusions(ExclusionsBuilder $builder): self
public function withExclusions(Node ...$exclusions): self
{
$this->exclusions = $builder;
array_push($this->exclusions, ...$exclusions);

return $this;
}
Expand Down Expand Up @@ -69,7 +67,7 @@ class: new Node\Stmt\Class_(null, [
new Node\Name('true'),
),
[
...$this->exclusions->getNode(),
...$this->exclusions,
new Node\Stmt\Expression(
new Node\Expr\Assign(
new Node\Expr\Variable('input'),
Expand All @@ -85,11 +83,6 @@ class: new Node\Stmt\Class_(null, [
),
],
),
new Node\Stmt\Expression(
new Node\Expr\Yield_(
new Node\Expr\Variable('input')
),
),
])
->getNode(),
],
Expand Down
7 changes: 7 additions & 0 deletions src/Plugin/Filtering/Configuration/Drop.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ public function getConfigTreeBuilder(): TreeBuilder
->then(asExpression())
->end()
->end()
->scalarNode('reason')
->cannotBeEmpty()
->validate()
->ifTrue(isExpression())
->then(asExpression())
->end()
->end()
->end()
->end()
;
Expand Down
1 change: 1 addition & 0 deletions src/Plugin/Filtering/Configuration/Reject.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public function getConfigTreeBuilder(): TreeBuilder
->end()
->end()
->scalarNode('reason')
->cannotBeEmpty()
->validate()
->ifTrue(isExpression())
->then(asExpression())
Expand Down
17 changes: 12 additions & 5 deletions src/Plugin/Filtering/Factory/Drop.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;

use function Kiboko\Component\SatelliteToolbox\Configuration\compileExpression;
use function Kiboko\Component\SatelliteToolbox\Configuration\compileValueWhenExpression;

class Drop implements Configurator\FactoryInterface
{
Expand Down Expand Up @@ -59,20 +60,26 @@ public function validate(array $config): bool
/**
* @throws Configurator\ConfigurationExceptionInterface
*/
public function compile(array $config): Filtering\Factory\Repository\Drop
public function compile(array $config): Repository\Drop
{
$interpreter = clone $this->interpreter;

$builder = new Filtering\Builder\Drop();

$repository = new Filtering\Factory\Repository\Drop($builder);
$repository = new Repository\Drop($builder);

$exclusionBuilder = new Filtering\Builder\ExclusionsBuilder();
foreach ($config as $condition) {
$builder->withExclusions(
compileExpression($interpreter, $condition['when'])
);
$exclusionBuilder
->withCondition(
compileExpression($interpreter, $condition['when']),
compileValueWhenExpression($interpreter, $condition['reason']),
)
;
}

$builder->withExclusions(...$exclusionBuilder->build());

return $repository;
}
}
12 changes: 7 additions & 5 deletions src/Plugin/Filtering/Factory/Reject.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,25 @@ public function validate(array $config): bool
/**
* @throws Configurator\ConfigurationExceptionInterface
*/
public function compile(array $config): Filtering\Factory\Repository\Reject
public function compile(array $config): Repository\Reject
{
$interpreter = clone $this->interpreter;

$builder = new Filtering\Builder\Reject();

$repository = new Filtering\Factory\Repository\Reject($builder);
$repository = new Repository\Reject($builder);

$exclusionBuilder = new Filtering\Builder\ExclusionsBuilder();
foreach ($config as $condition) {
$exclusionBuilder
->withCondition(
compileExpression($interpreter, $condition['when']),
\array_key_exists('reason', $condition) ? compileValueWhenExpression($interpreter, $condition['reason']) : null,
);
compileValueWhenExpression($interpreter, $condition['reason']),
)
;
}
$builder->withExclusions($exclusionBuilder);

$builder->withExclusions(...$exclusionBuilder->build());

return $repository;
}
Expand Down
7 changes: 3 additions & 4 deletions src/Plugin/Filtering/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace Kiboko\Component\Satellite\Plugin\Filtering;

use Kiboko\Component\Satellite\ExpressionLanguage as Satellite;
use Kiboko\Component\Satellite\Plugin\Filtering;
use Kiboko\Contract\Configurator;
use Symfony\Component\Config\Definition\Exception as Symfony;
use Symfony\Component\Config\Definition\Processor;
Expand All @@ -26,7 +25,7 @@ public function __construct(
private ExpressionLanguage $interpreter = new Satellite\ExpressionLanguage()
) {
$this->processor = new Processor();
$this->configuration = new Filtering\Configuration();
$this->configuration = new Configuration();
}

public function interpreter(): ExpressionLanguage
Expand Down Expand Up @@ -79,11 +78,11 @@ public function compile(array $config): Configurator\RepositoryInterface
}

if (\array_key_exists('reject', $config)) {
return (new Filtering\Factory\Reject($interpreter, $config['expression_language'] ?? []))->compile($config['reject']);
return (new Factory\Reject($interpreter, $config['expression_language'] ?? []))->compile($config['reject']);
}

if (\array_key_exists('drop', $config)) {
return (new Filtering\Factory\Drop($interpreter, $config['expression_language'] ?? []))->compile($config['drop']);
return (new Factory\Drop($interpreter, $config['expression_language'] ?? []))->compile($config['drop']);
}

throw new \RuntimeException('No possible pipeline step, expecting "extractor", "transformer" or "loader".');
Expand Down

0 comments on commit ff51a50

Please sign in to comment.