|
15 | 15 | use function explode;
|
16 | 16 | use function implode;
|
17 | 17 | use function in_array;
|
| 18 | +use function is_array; |
18 | 19 | use function is_string;
|
19 | 20 | use function json_encode;
|
20 | 21 | use function sprintf;
|
21 | 22 | use function str_replace;
|
| 23 | +use function strlen; |
22 | 24 | use function strtolower;
|
23 | 25 | use function trim;
|
24 | 26 |
|
@@ -101,7 +103,7 @@ public function __construct()
|
101 | 103 | return $v;
|
102 | 104 | }
|
103 | 105 |
|
104 |
| - $types = array_map(static fn ($type) => explode(' ', trim($type))[1], explode(',', $type->params)); |
| 106 | + $types = array_map(static fn ($type) => explode(' ', trim($type))[1], $this->splitTypes($type->params)); |
105 | 107 |
|
106 | 108 | return sprintf('[%s]', implode(',', array_map(
|
107 | 109 | fn (array $row) => sprintf('(%s)', implode(',', array_map(
|
@@ -167,17 +169,23 @@ public function __construct()
|
167 | 169 | return $this->get($innerType)($v, $innerType, true);
|
168 | 170 | }, $v),
|
169 | 171 | )),
|
170 |
| - 'Tuple' => function (array|string $v, Type $type) { |
171 |
| - if (is_string($v)) { |
| 172 | + 'Tuple' => function (mixed $v, Type $type) { |
| 173 | + if (! is_array($v)) { |
172 | 174 | return $v;
|
173 | 175 | }
|
174 | 176 |
|
175 |
| - $types = array_map(static fn ($p) => trim($p), explode(',', $type->params)); |
| 177 | + $innerTypes = $this->splitTypes($type->params); |
176 | 178 |
|
177 |
| - return '(' . implode( |
| 179 | + $innerExpression = implode( |
178 | 180 | ',',
|
179 |
| - array_map(fn (mixed $i) => $this->get($types[$i])($v[$i], null, true), array_keys($v)), |
180 |
| - ) . ')'; |
| 181 | + array_map(function (int $i) use ($innerTypes, $v) { |
| 182 | + $innerType = Type::fromString($innerTypes[$i]); |
| 183 | + |
| 184 | + return $this->get($innerType)($v[$i], $innerType, true); |
| 185 | + }, array_keys($v)), |
| 186 | + ); |
| 187 | + |
| 188 | + return '(' . $innerExpression . ')'; |
181 | 189 | },
|
182 | 190 | ];
|
183 | 191 | $this->registry = $registry;
|
@@ -254,4 +262,36 @@ private static function dateIntervalConverter(): Closure
|
254 | 262 | {
|
255 | 263 | return static fn (int|float $v) => $v;
|
256 | 264 | }
|
| 265 | + |
| 266 | + /** @return list<string> */ |
| 267 | + private function splitTypes(string $types): array |
| 268 | + { |
| 269 | + $result = []; |
| 270 | + $depth = 0; |
| 271 | + $current = ''; |
| 272 | + |
| 273 | + for ($i = 0; $i < strlen($types); $i++) { |
| 274 | + $char = $types[$i]; |
| 275 | + if ($char === '(') { |
| 276 | + $depth++; |
| 277 | + } elseif ($char === ')') { |
| 278 | + $depth--; |
| 279 | + } elseif ($char === ',' && $depth === 0) { |
| 280 | + $result[] = $current; |
| 281 | + $current = ''; |
| 282 | + |
| 283 | + continue; |
| 284 | + } |
| 285 | + |
| 286 | + $current .= $char; |
| 287 | + } |
| 288 | + |
| 289 | + $current = trim($current); |
| 290 | + |
| 291 | + if ($current !== '') { |
| 292 | + $result[] = $current; |
| 293 | + } |
| 294 | + |
| 295 | + return $result; |
| 296 | + } |
257 | 297 | }
|
0 commit comments