Skip to content

Commit 4b752d7

Browse files
committed
Introducing the ForbiddenStateError exception class
1 parent 16c79b9 commit 4b752d7

File tree

6 files changed

+97
-26
lines changed

6 files changed

+97
-26
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ All Notable changes to `bakame/http-strucured-fields` will be documented in this
1212
- `OrderedList::from` named constructor which accepts a variadic list of members items
1313
- `Token::fromString` named constructor which accepts `string` and `Stringable` object
1414
- `Parameter::values` returns an array of all the values contained inside the `Parameters` instance
15+
- **[BC Break]** `ForbiddenStateError` to replace `SerializationError`
1516
- **[BC Break]** `InnerList::fromList` to replace `InnerList::fromMembers`
1617
- **[BC Break]** `OrderedList::fromList` to replace `OrderedList::fromMembers`
1718
- **[BC Break]** `Parameter::value` to replace `InnerList::parameter` and `Item::parameter`
@@ -25,6 +26,7 @@ All Notable changes to `bakame/http-strucured-fields` will be documented in this
2526
- **[BC Break]** `OrderedList::__construct` is made private use `OrderedList::from` instead
2627
- **[BC Break]** `InnerList::__construct` is made private use `InnerList::fromList` instead
2728
- **[BC Break]** `Token::__construct` is made private use `Token::fromString` instead
29+
- **[BC Break]** `Parameter::get`, `Parameter::value`, `Parameter::pair` will throw `ForbiddenStateError` if the BareItem is in invalid state.
2830

2931
### Deprecated
3032

@@ -42,6 +44,7 @@ All Notable changes to `bakame/http-strucured-fields` will be documented in this
4244
- **[BC Break]** `InnerList::parameters()` replaced by `InnerList::parameters` public readonly property
4345
- **[BC Break]** `InnerList::merge()` use `InnerList::push()` or `InnerList::unshift()` instead
4446
- **[BC Break]** `OrderedList::merge()` use `OrderedList::push()` or `OrderedList::unshift()` instead
47+
- **[BC Break]** `SerializationError` use `ForbiddenStateError` instead
4548

4649
## [0.1.0] - 2022-03-18
4750

src/ForbiddenStateError.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Bakame\Http\StructuredFields;
4+
5+
use UnexpectedValueException;
6+
7+
final class ForbiddenStateError extends UnexpectedValueException implements StructuredFieldError
8+
{
9+
}

src/Parameters.php

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public function toHttpValue(): string
106106

107107
foreach ($this->members as $key => $val) {
108108
if (!$val->parameters->isEmpty()) {
109-
throw new SerializationError('Parameters instances can not contain parameterized Items.');
109+
throw new ForbiddenStateError('Parameters instances can not contain parameterized Items.');
110110
}
111111

112112
$value = ';'.$key;
@@ -125,6 +125,9 @@ public function count(): int
125125
return count($this->members);
126126
}
127127

128+
/**
129+
* Tells whether the container is empty or not.
130+
*/
128131
public function isEmpty(): bool
129132
{
130133
return [] === $this->members;
@@ -153,6 +156,8 @@ public function toPairs(): Iterator
153156
}
154157

155158
/**
159+
* Returns all the container keys.
160+
*
156161
* @return array<string>
157162
*/
158163
public function keys(): array
@@ -161,27 +166,30 @@ public function keys(): array
161166
}
162167

163168
/**
169+
* Returns all containers Item values.
170+
*
164171
* @return array<string, Token|ByteSequence|float|int|bool|string>
165172
*/
166173
public function values(): array
167174
{
168175
return array_map(fn (Item $item): Token|ByteSequence|float|int|bool|string => $item->value, $this->members);
169176
}
170177

171-
public function value(string $key): Token|ByteSequence|float|int|bool|string|null
172-
{
173-
if (!array_key_exists($key, $this->members)) {
174-
return null;
175-
}
176-
177-
return $this->members[$key]->value;
178-
}
179-
178+
/**
179+
* Tells whether the key is present in the container.
180+
*/
180181
public function has(string $key): bool
181182
{
182183
return array_key_exists($key, $this->members);
183184
}
184185

186+
/**
187+
* Returns the Item associated to the key.
188+
*
189+
* @throws SyntaxError if the key is invalid
190+
* @throws InvalidOffset if the key is not found
191+
* @throws ForbiddenStateError if the found item is in invalid state
192+
*/
185193
public function get(string $key): Item
186194
{
187195
self::validateKey($key);
@@ -190,9 +198,36 @@ public function get(string $key): Item
190198
throw InvalidOffset::dueToKeyNotFound($key);
191199
}
192200

193-
return $this->members[$key];
201+
$item = $this->members[$key];
202+
if (!$item->parameters->isEmpty()) {
203+
throw new ForbiddenStateError('Parameters instances can not contain parameterized Items.');
204+
}
205+
206+
return $item;
194207
}
195208

209+
/**
210+
* Returns the Item value of a specific key if it exists and is valid otherwise returns null.
211+
*
212+
* @throws ForbiddenStateError if the found item is in invalid state
213+
*/
214+
public function value(string $key): Token|ByteSequence|float|int|bool|string|null
215+
{
216+
if (!array_key_exists($key, $this->members)) {
217+
return null;
218+
}
219+
220+
$item = $this->members[$key];
221+
if (!$item->parameters->isEmpty()) {
222+
throw new ForbiddenStateError('Parameters instances can not contain parameterized Items.');
223+
}
224+
225+
return $item->value;
226+
}
227+
228+
/**
229+
* Tells whether the index is present in the container.
230+
*/
196231
public function hasPair(int $index): bool
197232
{
198233
return null !== $this->filterIndex($index);
@@ -210,6 +245,11 @@ private function filterIndex(int $index): int|null
210245
}
211246

212247
/**
248+
* Returns the key-item pair positionned at a given index.
249+
*
250+
* @throws InvalidOffset if the index is not found
251+
* @throws ForbiddenStateError if the found item is in invalid state
252+
*
213253
* @return array{0:string, 1:Item}
214254
*/
215255
public function pair(int $index): array
@@ -219,10 +259,12 @@ public function pair(int $index): array
219259
throw InvalidOffset::dueToIndexNotFound($index);
220260
}
221261

222-
return [
223-
array_keys($this->members)[$offset],
224-
array_values($this->members)[$offset],
225-
];
262+
$item = array_values($this->members)[$offset];
263+
if (!$item->parameters->isEmpty()) {
264+
throw new ForbiddenStateError('Parameters instances can not contain parameterized Items.');
265+
}
266+
267+
return [array_keys($this->members)[$offset], $item];
226268
}
227269

228270
/**

src/ParametersTest.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,15 +211,39 @@ public function it_can_merge_without_argument_and_not_throw(): void
211211
/**
212212
* @test
213213
*/
214-
public function it_fails_if_internal_parameters_are_changed_illegally(): void
214+
public function it_fails_if_internal_parameters_are_changed_illegally_1(): void
215215
{
216-
$this->expectException(SerializationError::class);
216+
$this->expectException(ForbiddenStateError::class);
217217

218218
$fields = Item::from('/terms', ['rel' => 'copyright', 'anchor' => '#foo']);
219219
$fields->parameters->get('anchor')->parameters->set('yolo', 42);
220220
$fields->toHttpValue();
221221
}
222222

223+
/**
224+
* @test
225+
*/
226+
public function it_fails_if_internal_parameters_are_changed_illegally_2(): void
227+
{
228+
$this->expectException(ForbiddenStateError::class);
229+
230+
$fields = Item::from('/terms', ['rel' => 'copyright', 'anchor' => '#foo']);
231+
$fields->parameters->get('anchor')->parameters->set('yolo', 42);
232+
$fields->parameters->get('anchor');
233+
}
234+
235+
/**
236+
* @test
237+
*/
238+
public function it_fails_if_internal_parameters_are_changed_illegally_3(): void
239+
{
240+
$this->expectException(ForbiddenStateError::class);
241+
242+
$fields = Item::from('/terms', ['rel' => 'copyright', 'anchor' => '#foo']);
243+
$fields->parameters->get('anchor')->parameters->set('yolo', 42);
244+
$fields->parameters->value('anchor');
245+
}
246+
223247
/**
224248
* @test
225249
*/

src/SerializationError.php

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/StructuredField.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ interface StructuredField
88
{
99
/**
1010
* Returns the serialize-representation of the Structured Field as a textual HTTP field value.
11+
*
12+
* @throws ForbiddenStateError If a component of the object is in invalid state
1113
*/
1214
public function toHttpValue(): string;
1315
}

0 commit comments

Comments
 (0)