|
10 | 10 | use Stringable; |
11 | 11 |
|
12 | 12 | use function array_filter; |
| 13 | +use function array_is_list; |
13 | 14 | use function array_map; |
14 | 15 | use function array_replace; |
15 | 16 | use function array_splice; |
|
18 | 19 | use function implode; |
19 | 20 | use function is_array; |
20 | 21 | use function is_int; |
| 22 | +use function is_iterable; |
21 | 23 |
|
22 | 24 | use const ARRAY_FILTER_USE_KEY; |
23 | 25 |
|
24 | 26 | /** |
25 | 27 | * @see https://www.rfc-editor.org/rfc/rfc8941.html#name-lists |
26 | 28 | * |
| 29 | + * @phpstan-import-type SfItem from StructuredField |
27 | 30 | * @phpstan-import-type SfMember from StructuredField |
28 | 31 | * @phpstan-import-type SfMemberInput from StructuredField |
29 | 32 | * @phpstan-import-type SfInnerListPair from InnerList |
@@ -79,16 +82,40 @@ public static function fromHttpValue(Stringable|string $httpValue, ListParser $p |
79 | 82 | } |
80 | 83 |
|
81 | 84 | /** |
82 | | - * @param iterable<SfInnerListPair|SfItemPair> $pairs |
| 85 | + * @param iterable<SfInnerListPair|SfItemPair>|MemberList<int, SfItem> $pairs |
83 | 86 | */ |
84 | 87 | public static function fromPairs(iterable $pairs): self |
85 | 88 | { |
86 | | - $members = []; |
87 | | - foreach ($pairs as [$member, $parameters]) { |
88 | | - $members[] = is_iterable($member) ? InnerList::fromPair([$member, $parameters]) : Item::fromPair([$member, $parameters]); |
89 | | - } |
| 89 | + $converter = function (mixed $pair): InnerList|Item { |
| 90 | + if ($pair instanceof ParameterAccess) { |
| 91 | + return $pair; /* @phpstan-ignore-line */ |
| 92 | + } |
| 93 | + |
| 94 | + if (!is_array($pair)) { |
| 95 | + return Item::new($pair); /* @phpstan-ignore-line */ |
| 96 | + } |
90 | 97 |
|
91 | | - return self::new(...$members); |
| 98 | + if (!array_is_list($pair)) { |
| 99 | + throw new SyntaxError('The pair must be represented by an array as a list.'); |
| 100 | + } |
| 101 | + |
| 102 | + if (2 !== count($pair)) { |
| 103 | + throw new SyntaxError('The pair first member is the item value; its second member is the item parameters.'); |
| 104 | + } |
| 105 | + |
| 106 | + [$member, $parameters] = $pair; |
| 107 | + |
| 108 | + return is_iterable($member) ? InnerList::fromPair([$member, $parameters]) : Item::fromPair([$member, $parameters]); |
| 109 | + }; |
| 110 | + |
| 111 | + return match (true) { |
| 112 | + $pairs instanceof MemberList => new self($pairs), |
| 113 | + default => new self(...(function (iterable $pairs) use ($converter) { |
| 114 | + foreach ($pairs as $member) { |
| 115 | + yield $converter($member); |
| 116 | + } |
| 117 | + })($pairs)), |
| 118 | + }; |
92 | 119 | } |
93 | 120 |
|
94 | 121 | /** |
|
0 commit comments