Skip to content

Commit b25b5d0

Browse files
authored
PHPLIB-1740: Accept iterable for custom encoders (#1790)
1 parent cfae2e1 commit b25b5d0

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

src/Builder/BuilderEncoder.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
use WeakReference;
3333

3434
use function array_key_exists;
35+
use function is_array;
3536
use function is_object;
37+
use function iterator_to_array;
3638

3739
/** @template-implements Encoder<Type|stdClass|array|string|int, Pipeline|StageInterface|ExpressionInterface|QueryInterface> */
3840
final class BuilderEncoder implements Encoder
@@ -46,11 +48,15 @@ final class BuilderEncoder implements Encoder
4648
/** @var array<class-string, Encoder|null> */
4749
private array $cachedEncoders = [];
4850

49-
/** @param array<class-string, Encoder> $encoders */
50-
public function __construct(array $encoders = [])
51+
/** @param iterable<class-string, Encoder> $encoders */
52+
public function __construct(iterable $encoders = [])
5153
{
5254
$self = WeakReference::create($this);
5355

56+
if (! is_array($encoders)) {
57+
$encoders = iterator_to_array($encoders);
58+
}
59+
5460
$this->encoders = $encoders + [
5561
Pipeline::class => new PipelineEncoder($self),
5662
Variable::class => new VariableEncoder(),

tests/Builder/BuilderEncoderTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,48 @@ public function encode(mixed $value): mixed
423423
$this->assertSamePipeline($expected, $pipeline, $codec);
424424
}
425425

426+
public function testCustomEncoderIterable(): void
427+
{
428+
$customEncoders = static function (): Generator {
429+
yield FieldPathInterface::class => new class implements Encoder {
430+
use EncodeIfSupported;
431+
432+
public function canEncode(mixed $value): bool
433+
{
434+
return $value instanceof FieldPathInterface;
435+
}
436+
437+
public function encode(mixed $value): mixed
438+
{
439+
return '$prefix.' . $value->name;
440+
}
441+
};
442+
};
443+
444+
$codec = new BuilderEncoder($customEncoders());
445+
446+
$pipeline = new Pipeline(
447+
Stage::project(
448+
threeFavorites: Expression::slice(
449+
Expression::arrayFieldPath('items'),
450+
n: 3,
451+
),
452+
),
453+
);
454+
455+
$expected = [
456+
[
457+
'$project' => [
458+
'threeFavorites' => [
459+
'$slice' => ['$prefix.items', 3],
460+
],
461+
],
462+
],
463+
];
464+
465+
$this->assertSamePipeline($expected, $pipeline, $codec);
466+
}
467+
426468
/** @param list<array<string, mixed>> $expected */
427469
private static function assertSamePipeline(array $expected, Pipeline $pipeline, $codec = new BuilderEncoder()): void
428470
{

0 commit comments

Comments
 (0)