|
18 | 18 | { |
19 | 19 | public function forProperty(PropertyReflector $property): ?Caster |
20 | 20 | { |
| 21 | + $type = $property->getType(); |
| 22 | + |
21 | 23 | // Get CastWith from the property |
22 | 24 | $castWith = $property->getAttribute(CastWith::class); |
23 | 25 |
|
24 | | - $type = $property->getType(); |
25 | | - |
26 | | - // Get CastWith from the property's type |
| 26 | + // Get CastWith from the property's type if there's no property-defined CastWith |
27 | 27 | if ($castWith === null) { |
28 | 28 | try { |
29 | | - $castWith = $type->asClass()->getAttribute(CastWith::class); |
| 29 | + $castWith = $type->asClass()->getAttribute(CastWith::class, recursive: true); |
30 | 30 | } catch (ReflectionException) { |
31 | 31 | // Could not resolve CastWith from the type |
32 | 32 | } |
33 | 33 | } |
34 | 34 |
|
| 35 | + // Return the caster if defined with CastWith |
35 | 36 | if ($castWith !== null) { |
36 | 37 | // Resolve the caster from the container |
37 | 38 | return get($castWith->className); |
38 | 39 | } |
39 | 40 |
|
| 41 | + $typeName = $type->getName(); |
| 42 | + |
40 | 43 | // Check if backed enum |
41 | 44 | if ($type->matches(BackedEnum::class)) { |
42 | | - return new EnumCaster($type->getName()); |
| 45 | + return new EnumCaster($typeName); |
43 | 46 | } |
44 | 47 |
|
45 | | - // Get Caster from built-in casters |
46 | | - return match ($type->getName()) { |
| 48 | + // Try a built-in caster |
| 49 | + $builtInCaster = match ($type->getName()) { |
47 | 50 | 'int' => new IntegerCaster(), |
48 | 51 | 'float' => new FloatCaster(), |
49 | 52 | 'bool' => new BooleanCaster(), |
50 | 53 | DateTimeImmutable::class, DateTimeInterface::class, DateTime::class => DateTimeCaster::fromProperty($property), |
51 | 54 | default => null, |
52 | 55 | }; |
| 56 | + |
| 57 | + if ($builtInCaster !== null) { |
| 58 | + return $builtInCaster; |
| 59 | + } |
| 60 | + |
| 61 | + // If the type's a class, we'll cast it with the generic object caster |
| 62 | + if ($type->isClass()) { |
| 63 | + return new ObjectCaster($type); |
| 64 | + } |
| 65 | + |
| 66 | + return null; |
53 | 67 | } |
54 | 68 | } |
0 commit comments