Skip to content

Commit 88127be

Browse files
committed
PHPLIB-1740: Accept iterable for custom encoders
1 parent cfae2e1 commit 88127be

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-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: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,46 @@ public function encode(mixed $value): mixed
423423
$this->assertSamePipeline($expected, $pipeline, $codec);
424424
}
425425

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

0 commit comments

Comments
 (0)