Skip to content

Commit cb9150a

Browse files
committed
feat(mapper): remove the need for CastWith and SerializeWith when using SerializeAs
1 parent e66e622 commit cb9150a

File tree

5 files changed

+20
-3
lines changed

5 files changed

+20
-3
lines changed

packages/database/src/Builder/ModelInspector.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Tempest\Database\Relation;
1313
use Tempest\Database\Table;
1414
use Tempest\Database\Virtual;
15+
use Tempest\Mapper\SerializeAs;
1516
use Tempest\Mapper\SerializeWith;
1617
use Tempest\Reflection\ClassReflector;
1718
use Tempest\Reflection\PropertyReflector;
@@ -153,6 +154,10 @@ public function getBelongsTo(string $name): ?BelongsTo
153154
return null;
154155
}
155156

157+
if ($property->getType()->asClass()->hasAttribute(SerializeAs::class)) {
158+
return null;
159+
}
160+
156161
if ($property->hasAttribute(HasOne::class)) {
157162
return null;
158163
}

packages/mapper/src/CasterFactory.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Tempest\Mapper;
66

77
use Closure;
8+
use Tempest\Mapper\Casters\DtoCaster;
89
use Tempest\Reflection\PropertyReflector;
910

1011
use function Tempest\get;
@@ -36,6 +37,10 @@ public function forProperty(PropertyReflector $property): ?Caster
3637
// Get CastWith from the property's type if there's no property-defined CastWith
3738
if ($castWith === null && $type->isClass()) {
3839
$castWith = $type->asClass()->getAttribute(CastWith::class, recursive: true);
40+
41+
if ($castWith === null && $type->asClass()->getAttribute(SerializeAs::class)) {
42+
$castWith = new CastWith(DtoCaster::class);
43+
}
3944
}
4045

4146
// Return the caster if defined with CastWith

packages/mapper/src/SerializeAs.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
/**
88
* Defines the name to use when serializing this class, instead of its fully qualified class name.
9+
* Using this attribute removes the need to specify a `DtoCaster` and `DtoSerializer`.
910
*/
1011
#[Attribute(Attribute::TARGET_CLASS)]
1112
final readonly class SerializeAs

packages/mapper/src/SerializerFactory.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Tempest\Mapper;
66

77
use Closure;
8+
use Tempest\Mapper\Serializers\DtoSerializer;
89
use Tempest\Reflection\ClassReflector;
910
use Tempest\Reflection\PropertyReflector;
1011
use Tempest\Reflection\TypeReflector;
@@ -73,6 +74,10 @@ public function forProperty(PropertyReflector $property): ?Serializer
7374
// Get SerializerWith from the property's type if there's no property-defined SerializerWith
7475
if ($serializeWith === null && $type->isClass()) {
7576
$serializeWith = $type->asClass()->getAttribute(SerializeWith::class, recursive: true);
77+
78+
if ($serializeWith === null && $type->asClass()->getAttribute(SerializeAs::class)) {
79+
$serializeWith = new SerializeWith(DtoSerializer::class);
80+
}
7681
}
7782

7883
// Return the serializer if defined with SerializerWith

tests/Integration/Database/DtoSerializationTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public function up(): QueryStatement
2727
{
2828
return new CreateTableStatement('model_with_settings')
2929
->primary()
30+
->text('title')
3031
->json('settings');
3132
}
3233

@@ -37,13 +38,14 @@ public function down(): null
3738
});
3839

3940
query(ModelWithSettings::class)
40-
->insert(new ModelWithSettings(new Settings(Theme::DARK)))
41+
->insert(new ModelWithSettings('model', new Settings(Theme::DARK)))
4142
->execute();
4243

4344
$model = query(ModelWithSettings::class)
4445
->select()
4546
->first();
4647

48+
$this->assertSame('model', $model->title);
4749
$this->assertSame(Theme::DARK, $model->settings->theme);
4850
}
4951
}
@@ -57,12 +59,11 @@ enum Theme: string
5759
final class ModelWithSettings
5860
{
5961
public function __construct(
62+
public string $title,
6063
public Settings $settings,
6164
) {}
6265
}
6366

64-
#[CastWith(DtoCaster::class)]
65-
#[SerializeWith(DtoSerializer::class)]
6667
#[SerializeAs('settings')]
6768
final class Settings
6869
{

0 commit comments

Comments
 (0)