<?php
/*
* This file is part of Chevere.
*
* (c) Rodolfo Berrios <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chevere\Parameter;
use Chevere\Parameter\Interfaces\TypeInterface;
use InvalidArgumentException;
use function Chevere\Message\message;
final class Type implements TypeInterface
{
public const CLASS_TYPES = [
self::PRIMITIVE_CLASS_NAME,
self::PRIMITIVE_INTERFACE_NAME,
];
private string $validator;
private string $primitive = '';
private string $typeHinting = '';
/**
* @param string $type A debug type
*/
public function __construct(
private string $type
) {
$this->setPrimitive();
$this->assertHasPrimitive();
$this->validator = self::TYPE_VALIDATORS[$this->primitive];
$this->typeHinting = $this->primitive;
if (in_array($this->primitive, self::CLASS_TYPES, true)) {
$this->typeHinting = $this->type;
}
}
public function validator(): callable
{
/** @var callable */
return $this->validator; // @phpstan-ignore-line
}
public function primitive(): string
{
return $this->primitive;
}
public function typeHinting(): string
{
return $this->typeHinting;
}
public function validate(mixed $variable): bool
{
if (is_object($variable) && $this->isAbleToValidateObjects()) {
return $this->validateObject($variable);
}
return $this->validator()($variable);
}
public function isScalar(): bool
{
return in_array($this->primitive, ['bool', 'int', 'float', 'string'], true);
}
private function isAbleToValidateObjects(): bool
{
return in_array($this->primitive, self::CLASS_TYPES, true);
}
private function validateObject(object $object): bool
{
return $object instanceof $this->type;
}
private function setPrimitive(): void
{
if (in_array($this->type, self::TYPE_ARGUMENTS, true)) {
$this->primitive = $this->type;
return;
}
if (class_exists($this->type)) {
$this->primitive = self::PRIMITIVE_CLASS_NAME;
} elseif (interface_exists($this->type)) {
$this->primitive = self::PRIMITIVE_INTERFACE_NAME;
}
}
private function assertHasPrimitive(): void
{
if ($this->primitive === '') {
throw new InvalidArgumentException(
(string) message(
"Type `%type%` doesn't exists",
type: $this->type
)
);
}
}
}
|