Repository navigation
Description
Context
The decoder currently exposes a generic input contract allowing data to be provided as a string, an array, or an object.
public function decode(string|array|object $data): SpatialInterface;Decoder strategies do not necessarily support all these input representations.
PHP parameter variance prevents a strategy implementing this generic contract from narrowing its decode() parameter to the input type it actually supports.
The strategy contracts must therefore explicitly describe their supported input representation while the main Decoder keeps its unified public API.
Objective
Introduce specialized decoder strategy interfaces for string, array, and object inputs and make the central Decoder responsible for validating compatibility and dispatching the decoding operation.
Implementation
Make DecoderStrategyInterface the common marker interface for all decoder strategies.
Introduce the following specialized contracts:
interface StringDecoderStrategyInterface extends DecoderStrategyInterface
{
public function decode(string $data): SpatialInterface;
}
interface ArrayDecoderStrategyInterface extends DecoderStrategyInterface
{
/**
* @param array<string, mixed> $data
*/
public function decode(array $data): SpatialInterface;
}
interface ObjectDecoderStrategyInterface extends DecoderStrategyInterface
{
public function decode(object $data): SpatialInterface;
}A strategy may implement one or several specialized contracts.
Keep the public decoder contract unchanged:
public function decode(string|array|object $data): SpatialInterface;Decoder::decode() must verify that the configured strategy implements the contract corresponding to the supplied input:
| Input | Required strategy contract |
|---|---|
string |
StringDecoderStrategyInterface |
array |
ArrayDecoderStrategyInterface |
object |
ObjectDecoderStrategyInterface |
When compatible, the decoder delegates the input to the strategy.
When incompatible, the strategy must not be invoked.
Exception
Introduce:
final class InvalidArgumentException extends \InvalidArgumentException implements DecoderExceptionInterface
{
}The exception must be thrown when the PHP type supplied to Decoder::decode() is part of its public contract but is not supported by the currently configured strategy.
Acceptance criteria
DecoderStrategyInterfaceis the common marker interface for decoder strategies.StringDecoderStrategyInterfaceacceptsstring.ArrayDecoderStrategyInterfaceacceptsarray.ObjectDecoderStrategyInterfaceacceptsobject.- All specialized interfaces extend
DecoderStrategyInterface. - A strategy may implement multiple specialized interfaces.
DecoderInterface::decode()continues to acceptstring|array|object.Decoder::decode()checks compatibility between the supplied input and the configured strategy.- Compatible inputs are delegated to the strategy.
- Incompatible inputs are rejected before the strategy is invoked.
- An incompatible input throws the library
InvalidArgumentException. InvalidArgumentExceptionextends\InvalidArgumentException.InvalidArgumentExceptionimplementsDecoderExceptionInterface.- Tests cover each specialized input contract.
- Tests cover incompatible input/strategy combinations.
- Tests cover a strategy implementing multiple input contracts.
- All existing quality and CI gates remain green.
Out of scope
- Migration of existing concrete decoder strategies to the new contracts.
- Public API documentation.
- New input representations.
- Automatic conversion between input representations.
- Changes to format-specific decoding or validation rules.
Activity
[-]Introduce typed strategy contracts and decoder dispatch[/-][+]Story: Introduce typed strategy contracts and decoder dispatch[/+]