From 8e054fab595e31ced8d4d61d2a4b8b388eb2f6ca Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Sun, 19 Oct 2025 20:16:54 +0800 Subject: [PATCH] improve: support enum casting in data objects --- src/support/src/DataObject.php | 20 +++++++++++++++----- tests/Support/DataObjectTest.php | 15 +++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/support/src/DataObject.php b/src/support/src/DataObject.php index 02f5e939..6629a93a 100644 --- a/src/support/src/DataObject.php +++ b/src/support/src/DataObject.php @@ -220,8 +220,10 @@ protected static function getDependencyFromUnionType(ReflectionUnionType $type): { foreach ($type->getTypes() as $namedType) { $className = $namedType->getName(); - if (is_subclass_of($className, DataObject::class) - || is_subclass_of($className, DateTimeInterface::class)) { + if ( + is_subclass_of($className, DataObject::class) + || is_subclass_of($className, DateTimeInterface::class) + ) { return $namedType; } } @@ -284,10 +286,18 @@ protected static function resolveDependenciesMap(string $class, array &$visited ]; continue; } + $dataKey = static::isAutoCasting() + ? static::convertPropertyToDataKey($property->getName()) + : $property->getName(); + if (enum_exists($typeName)) { + $result[$dataKey] = [ + 'handler' => [$typeName, 'from'], + 'nullable' => $allowsNull, + 'children' => [], + ]; + continue; + } if ($resolver = $customizedDependencies[$typeName] ?? null) { - $dataKey = static::isAutoCasting() - ? static::convertPropertyToDataKey($property->getName()) - : $property->getName(); $result[$dataKey] = [ 'handler' => $resolver, 'nullable' => $allowsNull, diff --git a/tests/Support/DataObjectTest.php b/tests/Support/DataObjectTest.php index ff8a7066..2746e1cb 100644 --- a/tests/Support/DataObjectTest.php +++ b/tests/Support/DataObjectTest.php @@ -255,6 +255,7 @@ public function testMakeWithoutAutoResolve(): void 'city' => 'New York', 'zipCode' => '10001', ], + 'gender' => TestGenderEnum::Male, 'created_at' => '2023-01-01 12:00:00', ]; @@ -265,6 +266,7 @@ public function testMakeWithoutAutoResolve(): void $this->assertSame(['street' => '123 Main St', 'city' => 'New York', 'zipCode' => '10001'], $user->address); $this->assertIsString($user->createdAt); $this->assertSame('2023-01-01 12:00:00', $user->createdAt); + $this->assertSame(TestGenderEnum::Male, $user->gender); } /** @@ -279,6 +281,7 @@ public function testMakeWithAutoResolveDataObject(): void 'city' => 'New York', 'zip_code' => '10001', ], + 'gender' => 'male', 'created_at' => '2023-01-01 12:00:00', ]; @@ -291,6 +294,7 @@ public function testMakeWithAutoResolveDataObject(): void $this->assertSame('10001', $user->address->zipCode); $this->assertInstanceOf(DateTime::class, $user->createdAt); $this->assertSame('2023-01-01 12:00:00', $user->createdAt->format('Y-m-d H:i:s')); + $this->assertSame(TestGenderEnum::Male, $user->gender); } /** @@ -307,6 +311,7 @@ public function testMakeWithAutoResolveDeepNesting(): void 'city' => 'Boston', 'zip_code' => '02101', ], + 'gender' => 'male', 'created_at' => '2023-06-15 09:30:00', ], ]; @@ -320,6 +325,7 @@ public function testMakeWithAutoResolveDeepNesting(): void $this->assertSame('456 Oak Ave', $company->employee->address->street); $this->assertSame('Boston', $company->employee->address->city); $this->assertInstanceOf(DateTime::class, $company->employee->createdAt); + $this->assertSame(TestGenderEnum::Male, $company->employee->gender); } /** @@ -331,6 +337,7 @@ public function testMakeWithAutoResolveNullValues(): void 'name' => 'John Doe', 'address' => null, 'created_at' => null, + 'gender' => 'male', ]; $user = TestUserDataObject::make($data, true); @@ -338,6 +345,7 @@ public function testMakeWithAutoResolveNullValues(): void $this->assertSame('John Doe', $user->name); $this->assertNull($user->address); $this->assertNull($user->createdAt); + $this->assertSame(TestGenderEnum::Male, $user->gender); } protected function getData(): array @@ -421,6 +429,7 @@ class TestUserDataObject extends DataObject { public function __construct( public string $name, + public TestGenderEnum $gender, public TestAddressDataObject|array|null $address, public DateTime|string|null $createdAt, ) { @@ -438,3 +447,9 @@ public function __construct( ) { } } + +enum TestGenderEnum: string +{ + case Male = 'male'; + case Female = 'female'; +}