$decoders */ public function __construct( protected array $decoders = [], protected ?DriverInterface $driver = null, ) { // } /** * Static factory method to create input handler for both image and color handling. * * @param array $decoders */ public static function usingDecoders(array $decoders, ?DriverInterface $driver = null): self { return new self($decoders, $driver); } /** * {@inheritdoc} * * @see InputHandlerInterface::handle() * * @throws InvalidArgumentException * @throws NotSupportedException * @throws DriverException */ public function handle(mixed $input): ImageInterface|ColorInterface { if ($input === null) { throw new InvalidArgumentException('Unable to decode from null'); } if ($input === '') { throw new InvalidArgumentException('Unable to decode from empty string'); } // if handler has only one single decoder run it can run directly if (count($this->decoders) === 1) { return $this->decoders()->current()->decode($input); } // multiple decoders: try to find the matching decoder for the input foreach ($this->decoders() as $decoder) { if ($decoder->supports($input)) { return $decoder->decode($input); } } throw new NotSupportedException('Unprocessable input'); } /** * Yield all decoders. * * @throws InvalidArgumentException * @throws DriverException */ private function decoders(): Generator { foreach ($this->decoders as $decoder) { yield $this->decoder($decoder); } } /** * Resolve the given classname or object to a decoder object. * * @throws InvalidArgumentException * @throws DriverException */ private function decoder(string|DecoderInterface $decoder): DecoderInterface { if (is_string($decoder)) { if (!is_subclass_of($decoder, DecoderInterface::class)) { throw new InvalidArgumentException('Decoder must implement ' . DecoderInterface::class); } $decoder = new $decoder(); } if ($this->driver === null) { return $decoder; } try { return $this->driver->specializeDecoder($decoder); } catch (NotSupportedException $e) { throw new DriverException( 'Failed to resolve decoder ' . $decoder::class . ' with driver ' . $this->driver::class, previous: $e, ); } } }