22
33namespace Tempest \Mapper \Serializers ;
44
5+ use BackedEnum ;
6+ use JsonSerializable ;
57use Tempest \Mapper \Exceptions \ValueCouldNotBeSerialized ;
68use Tempest \Mapper \MapperConfig ;
79use Tempest \Mapper \Serializer ;
10+ use Tempest \Reflection \ClassReflector ;
11+ use Tempest \Reflection \PropertyReflector ;
12+ use Tempest \Support \Arr ;
813use Tempest \Support \Json ;
9-
10- use function Tempest \map ;
14+ use UnitEnum ;
1115
1216final readonly class DtoSerializer implements Serializer
1317{
@@ -17,33 +21,33 @@ public function __construct(
1721
1822 public function serialize (mixed $ input ): array |string
1923 {
24+ // Support top-level arrays
2025 if (is_array ($ input )) {
21- // Handle top-level arrays
22- return Json \encode ($ this ->wrapWithTypeInfo ($ input ));
26+ return Json \encode ($ this ->serializeWithType ($ input ));
2327 }
2428
2529 if (! is_object ($ input )) {
2630 throw new ValueCouldNotBeSerialized ('object or array ' );
2731 }
2832
29- return Json \encode ($ this ->wrapWithTypeInfo ($ input ));
33+ return Json \encode ($ this ->serializeWithType ($ input ));
3034 }
3135
32- private function wrapWithTypeInfo (mixed $ input ): mixed
36+ private function serializeWithType (mixed $ input ): mixed
3337 {
34- if ($ input instanceof \ BackedEnum) {
38+ if ($ input instanceof BackedEnum) {
3539 return $ input ->value ;
3640 }
3741
38- if ($ input instanceof \ UnitEnum) {
42+ if ($ input instanceof UnitEnum) {
3943 return $ input ->name ;
4044 }
4145
4246 if (is_object ($ input )) {
4347 $ data = $ this ->extractObjectData ($ input );
4448
4549 foreach ($ data as $ key => $ value ) {
46- $ data [$ key ] = $ this ->wrapWithTypeInfo ($ value );
50+ $ data [$ key ] = $ this ->serializeWithType ($ value );
4751 }
4852
4953 $ type = $ this ->mapperConfig ->serializationMap [get_class ($ input )] ?? get_class ($ input );
@@ -55,25 +59,21 @@ private function wrapWithTypeInfo(mixed $input): mixed
5559 }
5660
5761 if (is_array ($ input )) {
58- return array_map ([ $ this , ' wrapWithTypeInfo ' ], $ input );
62+ return Arr \map_iterable ( $ input , $ this -> serializeWithType (...) );
5963 }
6064
6165 return $ input ;
6266 }
6367
6468 private function extractObjectData (object $ input ): array
6569 {
66- if ($ input instanceof \ JsonSerializable) {
70+ if ($ input instanceof JsonSerializable) {
6771 return $ input ->jsonSerialize ();
6872 }
6973
70- $ data = [];
71- $ class = new \ReflectionClass ($ input );
72-
73- foreach ($ class ->getProperties (\ReflectionProperty::IS_PUBLIC ) as $ property ) {
74- $ data [$ property ->getName ()] = $ property ->getValue ($ input );
75- }
76-
77- return $ data ;
74+ return Arr \map_with_keys (
75+ array: new ClassReflector ($ input )->getPublicProperties (),
76+ map: fn (PropertyReflector $ property ) => yield $ property ->getName () => $ property ->getValue ($ input ),
77+ );
7878 }
7979}
0 commit comments