Skip to content

Commit bd75848

Browse files
committed
hydrator builder variant
1 parent 774a87d commit bd75848

10 files changed

Lines changed: 129 additions & 239 deletions

src/CoreExtension.php

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,13 @@
55
namespace Patchlevel\Hydrator;
66

77
use Patchlevel\Hydrator\Guesser\BuiltInGuesser;
8-
use Patchlevel\Hydrator\Guesser\Guesser;
9-
use Patchlevel\Hydrator\Middleware\Middleware;
108
use Patchlevel\Hydrator\Middleware\TransformMiddleware;
119

12-
final class CoreExtension extends Extension
10+
final class CoreExtension implements Extension
1311
{
14-
/** @return iterable<Middleware|array{0: Middleware, 1?: int}> */
15-
public function middlewares(): iterable
12+
public function configure(HydratorBuilder $builder): void
1613
{
17-
yield new TransformMiddleware();
18-
}
19-
20-
/** @return iterable<Guesser|array{0: Guesser, 1?: int}> */
21-
public function guesser(): iterable
22-
{
23-
yield new BuiltInGuesser();
14+
$builder->addMiddleware(new TransformMiddleware(), -64);
15+
$builder->addGuesser(new BuiltInGuesser(), -64);
2416
}
2517
}

src/Cryptography/CryptographyExtension.php

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,18 @@
55
namespace Patchlevel\Hydrator\Cryptography;
66

77
use Patchlevel\Hydrator\Extension;
8-
use Patchlevel\Hydrator\Metadata\MetadataEnricher;
9-
use Patchlevel\Hydrator\Middleware\Middleware;
8+
use Patchlevel\Hydrator\HydratorBuilder;
109

11-
final class CryptographyExtension extends Extension
10+
final class CryptographyExtension implements Extension
1211
{
1312
public function __construct(
1413
private readonly PayloadCryptographer $cryptography,
1514
) {
1615
}
1716

18-
/** @return iterable<Middleware|array{0: Middleware, 1?: int}> */
19-
public function middlewares(): iterable
17+
public function configure(HydratorBuilder $builder): void
2018
{
21-
yield [new CryptographyMiddleware($this->cryptography), 64];
22-
}
23-
24-
/** @return iterable<MetadataEnricher|array{0: MetadataEnricher, 1?: int}> */
25-
public function metadataEnrichers(): iterable
26-
{
27-
yield [new CryptographyMetadataEnricher(), 64];
19+
$builder->addMetadataEnricher(new CryptographyMetadataEnricher(), 64);
20+
$builder->addMiddleware(new CryptographyMiddleware($this->cryptography), 64);
2821
}
2922
}

src/Extension.php

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,7 @@
44

55
namespace Patchlevel\Hydrator;
66

7-
use Patchlevel\Hydrator\Guesser\Guesser;
8-
use Patchlevel\Hydrator\Metadata\MetadataEnricher;
9-
use Patchlevel\Hydrator\Middleware\Middleware;
10-
11-
abstract class Extension
7+
interface Extension
128
{
13-
/** @return iterable<Middleware|array{0: Middleware, 1?: int}> */
14-
public function middlewares(): iterable
15-
{
16-
return [];
17-
}
18-
19-
/** @return iterable<MetadataEnricher|array{0: MetadataEnricher, 1?: int}> */
20-
public function metadataEnrichers(): iterable
21-
{
22-
return [];
23-
}
24-
25-
/** @return iterable<Guesser|array{0: Guesser, 1?: int}> */
26-
public function guesser(): iterable
27-
{
28-
return [];
29-
}
9+
public function configure(HydratorBuilder $builder): void;
3010
}

src/HydratorBuilder.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Patchlevel\Hydrator;
6+
7+
use Patchlevel\Hydrator\Guesser\ChainGuesser;
8+
use Patchlevel\Hydrator\Guesser\Guesser;
9+
use Patchlevel\Hydrator\Metadata\AttributeMetadataFactory;
10+
use Patchlevel\Hydrator\Metadata\MetadataEnricher;
11+
use Patchlevel\Hydrator\Middleware\Middleware;
12+
13+
use function array_merge;
14+
use function krsort;
15+
16+
final class HydratorBuilder
17+
{
18+
private bool $defaultLazy = false;
19+
20+
/** @var array<int, list<Middleware>> */
21+
private array $middlewares = [];
22+
23+
/** @var array<int, list<MetadataEnricher>> */
24+
private array $metadataEnrichers = [];
25+
26+
/** @var array<int, list<Guesser>> */
27+
private array $guessers = [];
28+
29+
/** @return $this */
30+
public function addMiddleware(Middleware $middleware, int $priority = 0): static
31+
{
32+
$this->middlewares[$priority][] = $middleware;
33+
34+
return $this;
35+
}
36+
37+
/** @return $this */
38+
public function addMetadataEnricher(MetadataEnricher $enricher, int $priority = 0): static
39+
{
40+
$this->metadataEnrichers[$priority][] = $enricher;
41+
42+
return $this;
43+
}
44+
45+
/** @return $this */
46+
public function addGuesser(Guesser $guesser, int $priority = 0): static
47+
{
48+
$this->guessers[$priority][] = $guesser;
49+
50+
return $this;
51+
}
52+
53+
public function enableDefaultLazy(bool $lazy = true): static
54+
{
55+
$this->defaultLazy = $lazy;
56+
57+
return $this;
58+
}
59+
60+
public function useExtension(Extension $extension): static
61+
{
62+
$extension->configure($this);
63+
64+
return $this;
65+
}
66+
67+
public function build(): Hydrator
68+
{
69+
krsort($this->middlewares);
70+
krsort($this->metadataEnrichers);
71+
krsort($this->guessers);
72+
73+
return new MetadataHydrator(
74+
new AttributeMetadataFactory(
75+
guesser: new ChainGuesser([...array_merge(...$this->guessers)]),
76+
),
77+
[...array_merge(...$this->middlewares)],
78+
[...array_merge(...$this->metadataEnrichers)],
79+
$this->defaultLazy,
80+
);
81+
}
82+
}

src/MetadataHydrator.php

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
namespace Patchlevel\Hydrator;
66

7-
use Patchlevel\Hydrator\Guesser\ChainGuesser;
8-
use Patchlevel\Hydrator\Guesser\Guesser;
97
use Patchlevel\Hydrator\Metadata\AttributeMetadataFactory;
108
use Patchlevel\Hydrator\Metadata\ClassMetadata;
119
use Patchlevel\Hydrator\Metadata\ClassNotFound;
@@ -17,8 +15,6 @@
1715
use ReflectionClass;
1816

1917
use function array_key_exists;
20-
use function array_merge;
21-
use function krsort;
2218

2319
use const PHP_VERSION_ID;
2420

@@ -121,55 +117,4 @@ private function metadata(string $class): ClassMetadata
121117

122118
return $metadata;
123119
}
124-
125-
/** @param iterable<Extension> $extensions */
126-
public static function create(
127-
iterable $extensions = [],
128-
bool $defaultLazy = false,
129-
): self {
130-
$extensions = [...$extensions, new CoreExtension()];
131-
132-
$middlewares = [];
133-
$enrichers = [];
134-
$guessers = [];
135-
136-
foreach ($extensions as $extension) {
137-
foreach ($extension->middlewares() as $entry) {
138-
if ($entry instanceof Middleware) {
139-
$middlewares[0][] = $entry;
140-
} else {
141-
$middlewares[$entry[1] ?? 0][] = $entry[0];
142-
}
143-
}
144-
145-
foreach ($extension->metadataEnrichers() as $entry) {
146-
if ($entry instanceof MetadataEnricher) {
147-
$enrichers[0][] = $entry;
148-
} else {
149-
$enrichers[$entry[1] ?? 0][] = $entry[0];
150-
}
151-
}
152-
153-
foreach ($extension->guesser() as $entry) {
154-
if ($entry instanceof Guesser) {
155-
$guessers[0][] = $entry;
156-
} else {
157-
$guessers[$entry[1] ?? 0][] = $entry[0];
158-
}
159-
}
160-
}
161-
162-
krsort($middlewares);
163-
krsort($enrichers);
164-
krsort($guessers);
165-
166-
return new self(
167-
new AttributeMetadataFactory(
168-
guesser: new ChainGuesser([...array_merge(...$guessers)]),
169-
),
170-
[...array_merge(...$middlewares)],
171-
[...array_merge(...$enrichers)],
172-
$defaultLazy,
173-
);
174-
}
175120
}

tests/Benchmark/HydratorBench.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
namespace Patchlevel\Hydrator\Tests\Benchmark;
66

7+
use Patchlevel\Hydrator\CoreExtension;
78
use Patchlevel\Hydrator\Hydrator;
8-
use Patchlevel\Hydrator\MetadataHydrator;
9+
use Patchlevel\Hydrator\HydratorBuilder;
910
use Patchlevel\Hydrator\Tests\Benchmark\Fixture\ProfileCreated;
1011
use Patchlevel\Hydrator\Tests\Benchmark\Fixture\ProfileId;
1112
use Patchlevel\Hydrator\Tests\Benchmark\Fixture\Skill;
@@ -18,7 +19,9 @@ final class HydratorBench
1819

1920
public function __construct()
2021
{
21-
$this->hydrator = MetadataHydrator::create();
22+
$this->hydrator = (new HydratorBuilder())
23+
->useExtension(new CoreExtension())
24+
->build();
2225
}
2326

2427
public function setUp(): void

tests/Benchmark/HydratorWithCryptographyBench.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44

55
namespace Patchlevel\Hydrator\Tests\Benchmark;
66

7+
use Patchlevel\Hydrator\CoreExtension;
78
use Patchlevel\Hydrator\Cryptography\CryptographyExtension;
89
use Patchlevel\Hydrator\Cryptography\SensitiveDataPayloadCryptographer;
910
use Patchlevel\Hydrator\Cryptography\Store\InMemoryCipherKeyStore;
1011
use Patchlevel\Hydrator\Hydrator;
11-
use Patchlevel\Hydrator\MetadataHydrator;
12+
use Patchlevel\Hydrator\HydratorBuilder;
1213
use Patchlevel\Hydrator\Tests\Benchmark\Fixture\ProfileCreated;
1314
use Patchlevel\Hydrator\Tests\Benchmark\Fixture\ProfileId;
1415
use Patchlevel\Hydrator\Tests\Benchmark\Fixture\Skill;
@@ -25,11 +26,10 @@ public function __construct()
2526
{
2627
$this->store = new InMemoryCipherKeyStore();
2728

28-
$this->hydrator = MetadataHydrator::create([
29-
new CryptographyExtension(
30-
SensitiveDataPayloadCryptographer::createWithDefaultSettings($this->store),
31-
),
32-
]);
29+
$this->hydrator = (new HydratorBuilder())
30+
->useExtension(new CoreExtension())
31+
->useExtension(new CryptographyExtension(SensitiveDataPayloadCryptographer::createWithDefaultSettings($this->store)))
32+
->build();
3333
}
3434

3535
public function setUp(): void

tests/Benchmark/HydratorWithLazyBench.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
namespace Patchlevel\Hydrator\Tests\Benchmark;
66

7+
use Patchlevel\Hydrator\CoreExtension;
78
use Patchlevel\Hydrator\Hydrator;
8-
use Patchlevel\Hydrator\MetadataHydrator;
9+
use Patchlevel\Hydrator\HydratorBuilder;
910
use Patchlevel\Hydrator\Tests\Benchmark\Fixture\ProfileCreated;
1011
use PhpBench\Attributes as Bench;
1112

@@ -16,7 +17,10 @@ final class HydratorWithLazyBench
1617

1718
public function __construct()
1819
{
19-
$this->hydrator = MetadataHydrator::create(defaultLazy: true);
20+
$this->hydrator = (new HydratorBuilder())
21+
->useExtension(new CoreExtension())
22+
->enableDefaultLazy()
23+
->build();
2024
}
2125

2226
public function setUp(): void

tests/Unit/Fixture/DummyExtension.php

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
 (0)