Skip to content

Commit a6a727d

Browse files
committed
Improve Outerlist constructors
1 parent 176f3cb commit a6a727d

File tree

5 files changed

+79
-30
lines changed

5 files changed

+79
-30
lines changed

README.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -667,22 +667,22 @@ of pairs.
667667
use Bakame\Http\StructuredFields\OuterList;
668668

669669
$list = OuterList::fromPairs([
670+
[
671+
['foo', 'bar'],
670672
[
671-
['foo', 'bar'],
672-
[
673-
['expire', $expire],
674-
['path', '/'],
675-
[ 'max-age', 2500],
676-
['secure', true],
677-
['httponly', true],
678-
['samesite', Token::fromString('lax')],
679-
]
680-
],
681-
[
682-
'coucoulesamis',
683-
[['a', false]],
673+
['expire', $expire],
674+
['path', '/'],
675+
[ 'max-age', 2500],
676+
['secure', true],
677+
['httponly', true],
678+
['samesite', Token::fromString('lax')],
684679
]
685-
]);
680+
],
681+
[
682+
'coucoulesamis',
683+
[['a', false]],
684+
]
685+
]);
686686
```
687687

688688
The pairs definitions are the same as for creating either a `InnerList` or an `Item` using

src/DataType.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,22 @@
88

99
enum DataType: string
1010
{
11-
case Item = 'item';
12-
case Parameters = 'parameters';
13-
case InnerList = 'innerlist';
1411
case List = 'list';
12+
case InnerList = 'innerlist';
13+
case Parameters = 'parameters';
1514
case Dictionary = 'dictionary';
15+
case Item = 'item';
1616

1717
/**
1818
* @throws StructuredFieldError
1919
*/
2020
public function parse(Stringable|string $httpValue): StructuredField
2121
{
2222
return match ($this) {
23-
self::Dictionary => Dictionary::fromHttpValue($httpValue),
24-
self::Parameters => Parameters::fromHttpValue($httpValue),
2523
self::List => OuterList::fromHttpValue($httpValue),
2624
self::InnerList => InnerList::fromHttpValue($httpValue),
25+
self::Parameters => Parameters::fromHttpValue($httpValue),
26+
self::Dictionary => Dictionary::fromHttpValue($httpValue),
2727
self::Item => Item::fromHttpValue($httpValue),
2828
};
2929
}
@@ -34,10 +34,10 @@ public function parse(Stringable|string $httpValue): StructuredField
3434
public function build(iterable $data): string
3535
{
3636
return (match ($this) {
37-
self::Dictionary => Dictionary::fromPairs($data),
38-
self::Parameters => Parameters::fromPairs($data),
3937
self::List => OuterList::fromPairs($data),
4038
self::InnerList => InnerList::fromPair([...$data]), /* @phpstan-ignore-line */
39+
self::Parameters => Parameters::fromPairs($data),
40+
self::Dictionary => Dictionary::fromPairs($data),
4141
self::Item => Item::fromPair([...$data]), /* @phpstan-ignore-line */
4242
})->toHttpValue();
4343
}

src/Dictionary.php

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,33 @@ public static function fromAssociative(iterable $members): self
9292
*/
9393
public static function fromPairs(iterable $pairs): self
9494
{
95+
$converter = function (mixed $pair): InnerList|Item {
96+
if ($pair instanceof ParameterAccess) {
97+
return $pair; /* @phpstan-ignore-line */
98+
}
99+
100+
if (!is_array($pair)) {
101+
return Item::new($pair); /* @phpstan-ignore-line */
102+
}
103+
104+
if (!array_is_list($pair)) {
105+
throw new SyntaxError('The pair must be represented by an array as a list.');
106+
}
107+
108+
if (2 !== count($pair)) {
109+
throw new SyntaxError('The pair first member is the item value; its second member is the item parameters.');
110+
}
111+
112+
[$member, $parameters] = $pair;
113+
114+
return is_iterable($member) ? InnerList::fromPair([$member, $parameters]) : Item::fromPair([$member, $parameters]);
115+
};
116+
95117
return match (true) {
96118
$pairs instanceof MemberOrderedMap => new self($pairs),
97-
default => new self((function (iterable $pairs) {
119+
default => new self((function (iterable $pairs) use ($converter) {
98120
foreach ($pairs as [$key, $member]) {
99-
yield $key => $member;
121+
yield $key => $converter($member);
100122
}
101123
})($pairs)),
102124
};

src/OuterList.php

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Stringable;
1111

1212
use function array_filter;
13+
use function array_is_list;
1314
use function array_map;
1415
use function array_replace;
1516
use function array_splice;
@@ -18,12 +19,14 @@
1819
use function implode;
1920
use function is_array;
2021
use function is_int;
22+
use function is_iterable;
2123

2224
use const ARRAY_FILTER_USE_KEY;
2325

2426
/**
2527
* @see https://www.rfc-editor.org/rfc/rfc8941.html#name-lists
2628
*
29+
* @phpstan-import-type SfItem from StructuredField
2730
* @phpstan-import-type SfMember from StructuredField
2831
* @phpstan-import-type SfMemberInput from StructuredField
2932
* @phpstan-import-type SfInnerListPair from InnerList
@@ -79,16 +82,40 @@ public static function fromHttpValue(Stringable|string $httpValue, ListParser $p
7982
}
8083

8184
/**
82-
* @param iterable<SfInnerListPair|SfItemPair> $pairs
85+
* @param iterable<SfInnerListPair|SfItemPair>|MemberList<int, SfItem> $pairs
8386
*/
8487
public static function fromPairs(iterable $pairs): self
8588
{
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+
}
9097

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+
};
92119
}
93120

94121
/**

tests/DataTypeTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function ti_will_generate_the_structured_field_text_represenation_for_dic
5050
}
5151

5252
#[Test]
53-
public function ti_will_generate_the_structured_field_text_represenation_for_list(): void
53+
public function it_will_generate_the_structured_field_text_represenation_for_list(): void
5454
{
5555
$data = [
5656
['coucoulesamis', [['a', false]]],

0 commit comments

Comments
 (0)