Skip to content

Commit

Permalink
Introducing the ForbiddenStateError exception class
Browse files Browse the repository at this point in the history
  • Loading branch information
nyamsprod committed Mar 20, 2022
1 parent 16c79b9 commit 4b752d7
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 26 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ All Notable changes to `bakame/http-strucured-fields` will be documented in this
- `OrderedList::from` named constructor which accepts a variadic list of members items
- `Token::fromString` named constructor which accepts `string` and `Stringable` object
- `Parameter::values` returns an array of all the values contained inside the `Parameters` instance
- **[BC Break]** `ForbiddenStateError` to replace `SerializationError`
- **[BC Break]** `InnerList::fromList` to replace `InnerList::fromMembers`
- **[BC Break]** `OrderedList::fromList` to replace `OrderedList::fromMembers`
- **[BC Break]** `Parameter::value` to replace `InnerList::parameter` and `Item::parameter`
Expand All @@ -25,6 +26,7 @@ All Notable changes to `bakame/http-strucured-fields` will be documented in this
- **[BC Break]** `OrderedList::__construct` is made private use `OrderedList::from` instead
- **[BC Break]** `InnerList::__construct` is made private use `InnerList::fromList` instead
- **[BC Break]** `Token::__construct` is made private use `Token::fromString` instead
- **[BC Break]** `Parameter::get`, `Parameter::value`, `Parameter::pair` will throw `ForbiddenStateError` if the BareItem is in invalid state.

### Deprecated

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

## [0.1.0] - 2022-03-18

Expand Down
9 changes: 9 additions & 0 deletions src/ForbiddenStateError.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Bakame\Http\StructuredFields;

use UnexpectedValueException;

final class ForbiddenStateError extends UnexpectedValueException implements StructuredFieldError
{
}
72 changes: 57 additions & 15 deletions src/Parameters.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public function toHttpValue(): string

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

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

/**
* Tells whether the container is empty or not.
*/
public function isEmpty(): bool
{
return [] === $this->members;
Expand Down Expand Up @@ -153,6 +156,8 @@ public function toPairs(): Iterator
}

/**
* Returns all the container keys.
*
* @return array<string>
*/
public function keys(): array
Expand All @@ -161,27 +166,30 @@ public function keys(): array
}

/**
* Returns all containers Item values.
*
* @return array<string, Token|ByteSequence|float|int|bool|string>
*/
public function values(): array
{
return array_map(fn (Item $item): Token|ByteSequence|float|int|bool|string => $item->value, $this->members);
}

public function value(string $key): Token|ByteSequence|float|int|bool|string|null
{
if (!array_key_exists($key, $this->members)) {
return null;
}

return $this->members[$key]->value;
}

/**
* Tells whether the key is present in the container.
*/
public function has(string $key): bool
{
return array_key_exists($key, $this->members);
}

/**
* Returns the Item associated to the key.
*
* @throws SyntaxError if the key is invalid
* @throws InvalidOffset if the key is not found
* @throws ForbiddenStateError if the found item is in invalid state
*/
public function get(string $key): Item
{
self::validateKey($key);
Expand All @@ -190,9 +198,36 @@ public function get(string $key): Item
throw InvalidOffset::dueToKeyNotFound($key);
}

return $this->members[$key];
$item = $this->members[$key];
if (!$item->parameters->isEmpty()) {
throw new ForbiddenStateError('Parameters instances can not contain parameterized Items.');
}

return $item;
}

/**
* Returns the Item value of a specific key if it exists and is valid otherwise returns null.
*
* @throws ForbiddenStateError if the found item is in invalid state
*/
public function value(string $key): Token|ByteSequence|float|int|bool|string|null
{
if (!array_key_exists($key, $this->members)) {
return null;
}

$item = $this->members[$key];
if (!$item->parameters->isEmpty()) {
throw new ForbiddenStateError('Parameters instances can not contain parameterized Items.');
}

return $item->value;
}

/**
* Tells whether the index is present in the container.
*/
public function hasPair(int $index): bool
{
return null !== $this->filterIndex($index);
Expand All @@ -210,6 +245,11 @@ private function filterIndex(int $index): int|null
}

/**
* Returns the key-item pair positionned at a given index.
*
* @throws InvalidOffset if the index is not found
* @throws ForbiddenStateError if the found item is in invalid state
*
* @return array{0:string, 1:Item}
*/
public function pair(int $index): array
Expand All @@ -219,10 +259,12 @@ public function pair(int $index): array
throw InvalidOffset::dueToIndexNotFound($index);
}

return [
array_keys($this->members)[$offset],
array_values($this->members)[$offset],
];
$item = array_values($this->members)[$offset];
if (!$item->parameters->isEmpty()) {
throw new ForbiddenStateError('Parameters instances can not contain parameterized Items.');
}

return [array_keys($this->members)[$offset], $item];
}

/**
Expand Down
28 changes: 26 additions & 2 deletions src/ParametersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,15 +211,39 @@ public function it_can_merge_without_argument_and_not_throw(): void
/**
* @test
*/
public function it_fails_if_internal_parameters_are_changed_illegally(): void
public function it_fails_if_internal_parameters_are_changed_illegally_1(): void
{
$this->expectException(SerializationError::class);
$this->expectException(ForbiddenStateError::class);

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

/**
* @test
*/
public function it_fails_if_internal_parameters_are_changed_illegally_2(): void
{
$this->expectException(ForbiddenStateError::class);

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

/**
* @test
*/
public function it_fails_if_internal_parameters_are_changed_illegally_3(): void
{
$this->expectException(ForbiddenStateError::class);

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

/**
* @test
*/
Expand Down
9 changes: 0 additions & 9 deletions src/SerializationError.php

This file was deleted.

2 changes: 2 additions & 0 deletions src/StructuredField.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ interface StructuredField
{
/**
* Returns the serialize-representation of the Structured Field as a textual HTTP field value.
*
* @throws ForbiddenStateError If a component of the object is in invalid state
*/
public function toHttpValue(): string;
}

0 comments on commit 4b752d7

Please sign in to comment.