|
4 | 4 |
|
5 | 5 | namespace Ardenexal\FHIRTools\Component\FHIRPath\Type; |
6 | 6 |
|
| 7 | +use Ardenexal\FHIRTools\Component\CodeGeneration\Attributes\FHIRPrimitive; |
| 8 | + |
7 | 9 | /** |
8 | 10 | * Resolves and validates FHIR types using the generated FHIR models. |
9 | 11 | * |
@@ -72,11 +74,22 @@ public function inferType(mixed $value): string |
72 | 74 | } |
73 | 75 |
|
74 | 76 | if (is_object($value)) { |
| 77 | + // Check if the object has a FHIRPrimitive attribute |
| 78 | + $ref = new \ReflectionClass($value); |
| 79 | + $attrs = $ref->getAttributes(FHIRPrimitive::class); |
| 80 | + |
| 81 | + if (!empty($attrs)) { |
| 82 | + /** @var FHIRPrimitive $primitive */ |
| 83 | + $primitive = $attrs[0]->newInstance(); |
| 84 | + |
| 85 | + return $primitive->primitiveType; |
| 86 | + } |
| 87 | + |
75 | 88 | // Get the class name and extract the FHIR type |
76 | 89 | $class = get_class($value); |
77 | 90 |
|
78 | 91 | // Check if it's a generated FHIR model |
79 | | - if (str_contains($class, '\\FHIR\\')) { |
| 92 | + if (str_contains($class, '\\FHIR\\') || str_contains($class, '\\Models\\')) { |
80 | 93 | // Extract the type name from the class name |
81 | 94 | $parts = explode('\\', $class); |
82 | 95 |
|
@@ -110,13 +123,18 @@ public function isOfType(mixed $value, string $typeName): bool |
110 | 123 | return true; |
111 | 124 | } |
112 | 125 |
|
| 126 | + // Case-insensitive match |
| 127 | + if (strcasecmp($actualType, $typeName) === 0) { |
| 128 | + return true; |
| 129 | + } |
| 130 | + |
113 | 131 | // Check for type compatibility |
114 | 132 | if ($typeName === 'Any') { |
115 | 133 | return true; |
116 | 134 | } |
117 | 135 |
|
118 | | - // Check if integer is compatible with decimal |
119 | | - if ($typeName === 'decimal' && $actualType === 'integer') { |
| 136 | + // Check if integer is compatible with decimal (case-insensitive) |
| 137 | + if (strcasecmp($typeName, 'decimal') === 0 && $actualType === 'integer') { |
120 | 138 | return true; |
121 | 139 | } |
122 | 140 |
|
@@ -148,12 +166,26 @@ public function castToType(mixed $value, string $typeName): mixed |
148 | 166 | return $value; |
149 | 167 | } |
150 | 168 |
|
| 169 | + // Extract value from FHIR primitives before casting |
| 170 | + $castValue = $value; |
| 171 | + if (is_object($value)) { |
| 172 | + $ref = new \ReflectionClass($value); |
| 173 | + $attrs = $ref->getAttributes(FHIRPrimitive::class); |
| 174 | + |
| 175 | + if (!empty($attrs) && property_exists($value, 'value')) { |
| 176 | + $castValue = $value->value; |
| 177 | + } |
| 178 | + } |
| 179 | + |
| 180 | + // Normalize typeName to lowercase for matching |
| 181 | + $normalizedType = strtolower($typeName); |
| 182 | + |
151 | 183 | // Primitive type casting |
152 | | - return match ($typeName) { |
153 | | - 'boolean' => $this->castToBoolean($value), |
154 | | - 'string' => $this->castToString($value), |
155 | | - 'integer' => $this->castToInteger($value), |
156 | | - 'decimal' => $this->castToDecimal($value), |
| 184 | + return match ($normalizedType) { |
| 185 | + 'boolean' => $this->castToBoolean($castValue), |
| 186 | + 'string' => $this->castToString($castValue), |
| 187 | + 'integer' => $this->castToInteger($castValue), |
| 188 | + 'decimal' => $this->castToDecimal($castValue), |
157 | 189 | default => throw new \InvalidArgumentException(sprintf('Cannot cast value to type "%s"', $typeName)), |
158 | 190 | }; |
159 | 191 | } |
|
0 commit comments