PHP Classes

File: src/Type.php

Recommend this page to a friend!
  Classes of Rodolfo Berrios Arce   Parameter   src/Type.php   Download  
File: src/Type.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Parameter
Validate function parameters with PHP attributes
Author: By
Last change:
Date: 20 days ago
Size: 2,794 bytes
 

Contents

Class file image Download
<?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
               
)
            );
        }
    }
}