Skip to content

Commit c1d1fe6

Browse files
committed
Improve method declaration in intercaes
1 parent f58a9f7 commit c1d1fe6

10 files changed

+104
-39
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ All Notable changes to `bakame/http-strucured-fields` will be documented in this
77
### Added
88

99
- **[BC Break]** `MemberContainer::remove` methods get added to the interface.
10+
- **[BC Break]** `MemberContainer::has` method accepts a variadic argument. All submitted indexes should be present for the method to return `true`
11+
- **[BC Break]** `MemberContainer::hasPair` method accepts a variadic argument. All submitted indexes should be present for the method to return `true`
1012

1113
### Fixed
1214

README.md

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,11 @@ use Bakame\Http\StructuredFields\Dictionary;
6161
$dictionary = Dictionary::fromHttpValue("a=?0, b, c=?1; foo=bar");
6262
```
6363

64-
The `fromHttpValue` named constructor returns an instance of the `Bakame\Http\StructuredFields\StructuredField` interface
65-
which provides a way to serialize back the object into a normalized RFC compliant HTTP field using the `toHttpValue` method.
64+
The `fromHttpValue` named constructor returns an instance of the `Bakame\Http\StructuredFields\StructuredField` interface.
65+
The interface provides a way to serialize back the object into a normalized RFC compliant HTTP field using the `toHttpValue` method.
6666

67-
To ease integration with current PHP frameworks and packages working with HTTP headers and trailers, each value object
68-
also exposes the `Stringable` interface method `__toString` which is an alias of the `toHttpValue` method.
67+
To ease integration with current PHP frameworks and HTTP related packages working with headers and trailers, each value object
68+
also exposes the `Stringable` interface method `__toString`, an alias of the `toHttpValue` method.
6969

7070
````php
7171
use Bakame\Http\StructuredFields\OuterList;
@@ -75,13 +75,12 @@ echo $list->toHttpValue(); // '("foo";a=1;b=2);lvl=5, ("bar" "baz");lvl=1'
7575
echo $list; // '("foo";a=1;b=2);lvl=5, ("bar" "baz");lvl=1'
7676
````
7777

78-
The library provides currently five (5) immutable value objects define inside the `Bakame\Http\StructuredFields` namespace:
78+
The library provides currently five (5) immutable value objects define inside the `Bakame\Http\StructuredFields` namespace
79+
with expose the `StructuredField` interface and expose a `fromHttpValue` named constructor:
7980

80-
- an [Item](item.md);
81-
- a [2 Ordered Map Containers](ordered-maps.md) `Dictionary` and `Parameters`;
82-
- a [2 List Containers](lists.md) `OuterList` and `InnerList`;
83-
84-
All five of them implement the `StructuredField` interface and expose a `fromHttpValue` named constructor.
81+
- an `Item`;
82+
- a 2 Ordered Map Containers `Dictionary` and `Parameters`;
83+
- a 2 List Containers `OuterList` and `InnerList`;
8584

8685
### Building and Updating Structured Fields
8786

@@ -136,8 +135,8 @@ echo $value->toHttpValue(); //"b=?0, a=bar;baz=42, c=@1671800423"
136135
echo $value; //"b=?0, a=bar;baz=42, c=@1671800423"
137136
```
138137

139-
Because we are using immutable value object any change to the value object will return a new instance with
140-
the changes implemented and leave the original instance unchanged.
138+
Because we are using immutable value objects any change to the value object will return a new instance with
139+
the changes applied and leave the original instance unchanged.
141140

142141
The same changes can be applied to List Containers but with adapted methods around list handling:
143142

@@ -231,6 +230,34 @@ $integer = Item::fromPair([42]);
231230
$integer->type(); //return Type::Integer
232231
```
233232

233+
### Accessing members of Structured Fields Containers.
234+
235+
All containers implement PHP `IteratorAggregate`, `Countable` and `ArrayAccess` interfaces for easy usage in your codebase.
236+
You also can access container members via the following shared methods
237+
238+
```php
239+
$container->has(string|int ...$offsets): bool;
240+
$container->get(string|int $offset): bool;
241+
$container->remove(string|int ...$offsets): bool;
242+
$container->hasMembers(): bool;
243+
$container->hasNotMembers(): bool;
244+
```
245+
246+
To avoid invalid states, the modifying methods from PHP `ArrayAccess` will throw a `ForbiddenOperation` if you try to
247+
use them:
248+
249+
```php
250+
use Bakame\Http\StructuredFields\Item;
251+
252+
$value = Item::from("Hello world", [
253+
'a' => 'foobar',
254+
]);
255+
$value->parameters()->has('b'); // return false
256+
$value->parameters()->has('22'); // return false the index does not exists
257+
```
258+
259+
260+
234261
## Contributing
235262

236263
Contributions are welcome and will be fully credited. Please see [CONTRIBUTING](.github/CONTRIBUTING.md) and [CODE OF CONDUCT](.github/CODE_OF_CONDUCT.md) for details.

src/Dictionary.php

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,15 @@ public function keys(): array
165165
return array_keys($this->members);
166166
}
167167

168-
public function has(string|int $offset): bool
168+
public function has(string|int ...$offsets): bool
169169
{
170-
return is_string($offset) && array_key_exists($offset, $this->members);
170+
foreach ($offsets as $offset) {
171+
if (!is_string($offset) || !array_key_exists($offset, $this->members)) {
172+
return false;
173+
}
174+
}
175+
176+
return [] !== $offsets;
171177
}
172178

173179
/**
@@ -183,15 +189,17 @@ public function get(string|int $offset): Value|InnerList
183189
return $this->members[$offset];
184190
}
185191

186-
public function hasPair(int $index): bool
192+
public function hasPair(int ...$indexes): bool
187193
{
188-
try {
189-
$this->filterIndex($index);
190-
191-
return true;
192-
} catch (InvalidOffset) {
193-
return false;
194+
foreach ($indexes as $index) {
195+
try {
196+
$this->filterIndex($index);
197+
} catch (InvalidOffset) {
198+
return false;
199+
}
194200
}
201+
202+
return [] !== $indexes;
195203
}
196204

197205
/**

src/DictionaryTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ public function it_fails_to_return_an_member_with_invalid_index(): void
103103
{
104104
$instance = Dictionary::create();
105105

106-
self::assertFalse($instance->hasPair(3));
106+
self::assertFalse($instance->hasPair(1, 2, 3));
107+
self::assertFalse($instance->hasPair());
107108

108109
$this->expectException(InvalidOffset::class);
109110

src/InnerList.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,15 @@ public function getIterator(): Iterator
142142
yield from $this->members;
143143
}
144144

145-
public function has(string|int $offset): bool
145+
public function has(string|int ...$offsets): bool
146146
{
147-
return null !== $this->filterIndex($offset);
147+
foreach ($offsets as $offset) {
148+
if (null === $this->filterIndex($offset)) {
149+
return false;
150+
}
151+
}
152+
153+
return [] !== $offsets;
148154
}
149155

150156
private function filterIndex(string|int $index): int|null

src/MemberContainer.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ public function hasMembers(): bool;
3232
public function get(string|int $offset): StructuredField;
3333

3434
/**
35-
* Tells whether the instance contain a members at the specified offset.
35+
* Tells whether the instance contain a members at the specified offsets.
3636
*/
37-
public function has(string|int $offset): bool;
37+
public function has(string|int ...$offsets): bool;
3838

3939
/**
4040
* Deletes members associated with the list of submitted keys.

src/MemberOrderedMap.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public function toPairs(): Iterator;
2323
/**
2424
* Tells whether a pair is attached to the given index position.
2525
*/
26-
public function hasPair(int $index): bool;
26+
public function hasPair(int ...$indexes): bool;
2727

2828
/**
2929
* Returns the item or the inner-list and its key as attached to the given

src/OuterList.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,15 @@ public function getIterator(): Iterator
104104
yield from $this->members;
105105
}
106106

107-
public function has(string|int $offset): bool
107+
public function has(string|int ...$offsets): bool
108108
{
109-
return null !== $this->filterIndex($offset);
109+
foreach ($offsets as $offset) {
110+
if (null === $this->filterIndex($offset)) {
111+
return false;
112+
}
113+
}
114+
115+
return [] !== $offsets;
110116
}
111117

112118
private function filterIndex(string|int $index): int|null

src/Parameters.php

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,15 @@ public function keys(): array
162162
return array_keys($this->members);
163163
}
164164

165-
public function has(string|int $offset): bool
165+
public function has(string|int ...$offsets): bool
166166
{
167-
return is_string($offset) && array_key_exists($offset, $this->members);
167+
foreach ($offsets as $offset) {
168+
if (!is_string($offset) || !array_key_exists($offset, $this->members)) {
169+
return false;
170+
}
171+
}
172+
173+
return [] !== $offsets;
168174
}
169175

170176
/**
@@ -180,15 +186,17 @@ public function get(string|int $offset): Value
180186
return $this->members[$offset];
181187
}
182188

183-
public function hasPair(int $index): bool
189+
public function hasPair(int ...$indexes): bool
184190
{
185-
try {
186-
$this->filterIndex($index);
187-
188-
return true;
189-
} catch (InvalidOffset) {
190-
return false;
191+
foreach ($indexes as $index) {
192+
try {
193+
$this->filterIndex($index);
194+
} catch (InvalidOffset) {
195+
return false;
196+
}
191197
}
198+
199+
return [] !== $indexes;
192200
}
193201

194202
/**

src/ParametersTest.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,19 @@ public function it_can_add_or_remove_members(): void
8484
self::assertFalse($deletedInstance->hasPair(1));
8585

8686
$addedInstance = $deletedInstance->append('foobar', Item::from('BarBaz'));
87+
8788
self::assertTrue($addedInstance->hasPair(1));
89+
self::assertFalse($addedInstance->hasPair(3, 23));
90+
self::assertFalse($addedInstance->hasPair());
91+
8892
$foundItem = $addedInstance->pair(1);
8993

9094
self::assertCount(2, $addedInstance);
9195
self::assertIsString($foundItem[1]->value());
9296
self::assertStringContainsString('BarBaz', $foundItem[1]->value());
9397

9498
$altInstance = $addedInstance->remove('foobar', 'string');
99+
95100
self::assertCount(0, $altInstance);
96101
self::assertFalse($altInstance->hasMembers());
97102
self::assertTrue($altInstance->hasNoMembers());
@@ -122,7 +127,9 @@ public function it_fails_to_return_an_member_with_invalid_key(): void
122127
$this->expectException(InvalidOffset::class);
123128

124129
$instance = Parameters::create();
125-
self::assertFalse($instance->has('foobar'));
130+
131+
self::assertFalse($instance->has('foobar', 'barbaz'));
132+
self::assertFalse($instance->has());
126133

127134
$instance->get('foobar');
128135
}

0 commit comments

Comments
 (0)