Skip to content

Commit 08ebf95

Browse files
committed
Add collection methods only(), onlyIn(), except(), exceptIn()
Also: - Add `Curler::getPublicHeaders()` - Add tests for new collection methods
1 parent b3fe4be commit 08ebf95

File tree

12 files changed

+298
-11
lines changed

12 files changed

+298
-11
lines changed

src/Toolkit/.gitignore

Whitespace-only changes.

src/Util/Concern/TCollection.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,58 @@ public function filter(callable $callback, int $mode = ICollection::CALLBACK_USE
119119
return $this->maybeReplaceItems($items, true);
120120
}
121121

122+
/**
123+
* @param TKey[] $keys
124+
* @return static A copy of the collection with items that have keys in
125+
* `$keys`.
126+
*/
127+
public function only(array $keys)
128+
{
129+
return $this->maybeReplaceItems(
130+
array_intersect_key($this->Items, array_flip($keys)),
131+
true
132+
);
133+
}
134+
135+
/**
136+
* @param array<TKey,true> $index
137+
* @return static A copy of the collection with items that have keys in
138+
* `$index`.
139+
*/
140+
public function onlyIn(array $index)
141+
{
142+
return $this->maybeReplaceItems(
143+
array_intersect_key($this->Items, $index),
144+
true
145+
);
146+
}
147+
148+
/**
149+
* @param TKey[] $keys
150+
* @return static A copy of the collection with items that have keys not in
151+
* `$keys`.
152+
*/
153+
public function except(array $keys)
154+
{
155+
return $this->maybeReplaceItems(
156+
array_diff_key($this->Items, array_flip($keys)),
157+
true
158+
);
159+
}
160+
161+
/**
162+
* @param array<TKey,true> $index
163+
* @return static A copy of the collection with items that have keys not in
164+
* `$index`.
165+
*/
166+
public function exceptIn(array $index)
167+
{
168+
return $this->maybeReplaceItems(
169+
array_diff_key($this->Items, $index),
170+
true
171+
);
172+
}
173+
122174
/**
123175
* @return static A copy of the collection with items starting from
124176
* `$offset`.

src/Util/Contract/ICollection.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,38 @@ public function filter(callable $callback, int $mode = ICollection::CALLBACK_USE
113113
*/
114114
public function find(callable $callback, int $mode = ICollection::CALLBACK_USE_VALUE);
115115

116+
/**
117+
* Reduce the collection to items with keys in an array
118+
*
119+
* @param TKey[] $keys
120+
* @return static
121+
*/
122+
public function only(array $keys);
123+
124+
/**
125+
* Reduce the collection to items with keys in an index
126+
*
127+
* @param array<TKey,true> $index
128+
* @return static
129+
*/
130+
public function onlyIn(array $index);
131+
132+
/**
133+
* Reduce the collection to items with keys not in an array
134+
*
135+
* @param TKey[] $keys
136+
* @return static
137+
*/
138+
public function except(array $keys);
139+
140+
/**
141+
* Reduce the collection to items with keys not in an index
142+
*
143+
* @param array<TKey,true> $index
144+
* @return static
145+
*/
146+
public function exceptIn(array $index);
147+
116148
/**
117149
* Extract a slice of the collection
118150
*

src/Util/Curler/Curler.php

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use Lkrms\Concern\HasBuilder;
66
use Lkrms\Concern\Immutable;
77
use Lkrms\Contract\Buildable;
8-
use Lkrms\Contract\ICollection;
98
use Lkrms\Curler\Catalog\CurlerProperty;
109
use Lkrms\Curler\Contract\ICurlerPager;
1110
use Lkrms\Curler\Exception\CurlerCurlErrorException;
@@ -506,9 +505,7 @@ public function __construct(
506505
$this->AlwaysPaginate = $alwaysPaginate;
507506
$this->ObjectAsArray = $objectAsArray;
508507

509-
/** @var array<string,true> */
510-
$index = Arr::toIndex(Arr::lower(HttpHeaderGroup::SENSITIVE));
511-
$this->SensitiveHeaderIndex = $index;
508+
$this->SensitiveHeaderIndex = Arr::toIndex(Arr::lower(HttpHeaderGroup::SENSITIVE));
512509
}
513510

514511
/**
@@ -601,6 +598,14 @@ public function with(string $property, $value)
601598
return $this->withPropertyValue($property, $value);
602599
}
603600

601+
/**
602+
* Get request headers that are not considered sensitive
603+
*/
604+
public function getPublicHeaders(): HttpHeadersInterface
605+
{
606+
return $this->Headers->exceptIn($this->SensitiveHeaderIndex);
607+
}
608+
604609
/**
605610
* @return $this
606611
*/
@@ -1058,10 +1063,7 @@ private function getCacheKey(): ?string
10581063

10591064
$key = $this->ResponseCacheKeyCallback
10601065
? ($this->ResponseCacheKeyCallback)($this)
1061-
: $this->Headers->filter(
1062-
fn(string $key) => !($this->SensitiveHeaderIndex[$key] ?? false),
1063-
ICollection::CALLBACK_USE_KEY
1064-
)->getLines('%s:%s');
1066+
: $this->getPublicHeaders()->getLines('%s:%s');
10651067
if ($this->Method === HttpRequestMethod::POST) {
10661068
$key[] = $this->Body;
10671069
}

src/Util/Curler/CurlerBuilder.php

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Util/Http/HttpHeaders.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,50 @@ public function filter(callable $callback, int $mode = ICollection::CALLBACK_USE
384384
return $changed ? $this->replaceHeaders(null, $index) : $this;
385385
}
386386

387+
/**
388+
* @inheritDoc
389+
*/
390+
public function only(array $keys)
391+
{
392+
return $this->onlyIn(Arr::toIndex($keys));
393+
}
394+
395+
/**
396+
* @inheritDoc
397+
*/
398+
public function onlyIn(array $index)
399+
{
400+
return $this->maybeReplaceHeaders(
401+
null,
402+
array_intersect_key(
403+
$this->Index,
404+
array_change_key_case($index, \CASE_LOWER)
405+
)
406+
);
407+
}
408+
409+
/**
410+
* @inheritDoc
411+
*/
412+
public function except(array $keys)
413+
{
414+
return $this->exceptIn(Arr::toIndex($keys));
415+
}
416+
417+
/**
418+
* @inheritDoc
419+
*/
420+
public function exceptIn(array $index)
421+
{
422+
return $this->maybeReplaceHeaders(
423+
null,
424+
array_diff_key(
425+
$this->Index,
426+
array_change_key_case($index, \CASE_LOWER)
427+
)
428+
);
429+
}
430+
387431
/**
388432
* @inheritDoc
389433
*/

src/Util/Utility/Arr.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ public static function spliceByKey(
771771
*
772772
* @param array<array-key,TKey> $array
773773
* @param TValue $value
774-
* @return array<TKey,TValue>
774+
* @return ($value is true ? array<TKey,true> : array<TKey,TValue>)
775775
*/
776776
public static function toIndex(array $array, $value = true): array
777777
{

src/Util/Utility/Get.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,6 @@ public static function code(
297297
): string {
298298
$eol = (string) self::eol($delimiter);
299299
$multiline = (bool) $eol;
300-
/** @var array<string,true> */
301300
$classes = Arr::toIndex($classes);
302301
return self::doCode(
303302
$value,

tests/unit/Util/Concept/TypedCollectionTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,22 @@ function ($item, $next, $prev) use (&$arr, &$arrNext, &$arrPrev): bool {
6868
$this->assertSame([$e2, $e1, null], $arrNext);
6969
$this->assertSame([null, $e0, $e2], $arrPrev);
7070

71+
$coll = $collection->only([0, 71, 'n']);
72+
$this->assertSame([0 => $e0, 'n' => $e1], $coll->all());
73+
$this->assertSame($coll, $coll->only([0, 71, 'n']));
74+
75+
$coll = $collection->onlyIn([2 => true, 'm' => true]);
76+
$this->assertSame([2 => $e2], $coll->all());
77+
$this->assertSame($coll, $coll->onlyIn([2 => true, 'm' => true]));
78+
79+
$coll = $collection->except([0, 71, 'n']);
80+
$this->assertSame([2 => $e2], $coll->all());
81+
$this->assertSame($coll, $coll->except([0, 71, 'n']));
82+
83+
$coll = $collection->exceptIn([0 => true, 1 => true, 2 => true]);
84+
$this->assertSame(['n' => $e1], $coll->all());
85+
$this->assertSame($coll, $coll->exceptIn([0 => true, 1 => true, 2 => true]));
86+
7187
$arr = $arrNext = $arrPrev = [];
7288
$found = $collection->find(
7389
function ($item, $next, $prev) use (&$arr, &$arrNext, &$arrPrev): bool {
@@ -136,6 +152,18 @@ function () use (&$count) {
136152
$coll = $collection->filter(fn() => true);
137153
$this->assertSame($collection, $coll);
138154

155+
$coll = $collection->only([]);
156+
$this->assertSame($collection, $coll);
157+
158+
$coll = $collection->onlyIn([]);
159+
$this->assertSame($collection, $coll);
160+
161+
$coll = $collection->except([]);
162+
$this->assertSame($collection, $coll);
163+
164+
$coll = $collection->exceptIn([]);
165+
$this->assertSame($collection, $coll);
166+
139167
$this->assertNull($collection->find(fn() => true));
140168

141169
$coll = $collection->slice(0);

tests/unit/Util/Concept/TypedListTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,22 @@ function ($item, $next, $prev) use (&$arr, &$arrNext, &$arrPrev): bool {
6969
$this->assertSame([$e1, $e2, null], $arrNext);
7070
$this->assertSame([null, $e0, $e1], $arrPrev);
7171

72+
$l = $list->only([2, 3, 4]);
73+
$this->assertSame([$e2], $l->all());
74+
$this->assertSame($l, $l->only([0, 1, 2]));
75+
76+
$l = $list->onlyIn([0 => true, 1 => true]);
77+
$this->assertSame([$e0, $e1], $l->all());
78+
$this->assertSame($l, $l->onlyIn([0 => true, 1 => true]));
79+
80+
$l = $list->except([2, 3, 4]);
81+
$this->assertSame([$e0, $e1], $l->all());
82+
$this->assertSame($l, $l->except([2, 3, 4]));
83+
84+
$l = $list->exceptIn([0 => true, 1 => true]);
85+
$this->assertSame([$e2], $l->all());
86+
$this->assertSame($l, $l->exceptIn([1 => true, 2 => true]));
87+
7288
$arr = $arrNext = $arrPrev = [];
7389
$found = $list->find(
7490
function ($item, $next, $prev) use (&$arr, &$arrNext, &$arrPrev): bool {
@@ -137,6 +153,18 @@ function () use (&$count) {
137153
$l = $list->filter(fn() => true);
138154
$this->assertSame($list, $l);
139155

156+
$l = $list->only([]);
157+
$this->assertSame($list, $l);
158+
159+
$l = $list->onlyIn([]);
160+
$this->assertSame($list, $l);
161+
162+
$l = $list->except([]);
163+
$this->assertSame($list, $l);
164+
165+
$l = $list->exceptIn([]);
166+
$this->assertSame($list, $l);
167+
140168
$this->assertNull($list->find(fn() => true));
141169

142170
$l = $list->slice(0);

0 commit comments

Comments
 (0)