Skip to content

Commit

Permalink
Add class type extended matching
Browse files Browse the repository at this point in the history
  • Loading branch information
SerafimArts committed Jan 14, 2025
1 parent 3bc7a86 commit fb412ca
Showing 1 changed file with 52 additions and 5 deletions.
57 changes: 52 additions & 5 deletions src/Type/ClassType/ClassTypeDenormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use TypeLang\Mapper\Exception\Mapping\RuntimeException;
use TypeLang\Mapper\Mapping\Metadata\ClassMetadata;
use TypeLang\Mapper\Mapping\Metadata\DiscriminatorMapMetadata;
use TypeLang\Mapper\Mapping\Metadata\PropertyMetadata;
use TypeLang\Mapper\Runtime\Context;
use TypeLang\Mapper\Runtime\Path\Entry\ObjectEntry;
use TypeLang\Mapper\Runtime\Path\Entry\ObjectPropertyEntry;
Expand All @@ -34,7 +35,56 @@ public function __construct(

public function match(mixed $value, Context $context): bool
{
return \is_object($value) || \is_array($value);
return (\is_array($value) || \is_object($value))
&& $this->matchRequiredProperties((array) $value, $context);
}

/**
* @throws \Throwable
*/
private function getPropertyType(PropertyMetadata $meta, Context $context): TypeInterface
{
// Fetch field type
$info = $meta->findTypeInfo();

if ($info === null) {
return $context->getTypeByDefinition('mixed');
}

return $info->getType();
}

/**
* @param array<array-key, mixed> $payload
*/
private function matchRequiredProperties(array $payload, Context $context): bool
{
foreach ($this->metadata->getProperties() as $meta) {
// Match property for existence
if (!\array_key_exists($meta->getExportName(), $payload)) {
// Skip all properties with defaults
if ($meta->hasDefaultValue()) {
continue;
}

return false;
}

// Fetch field value and type
try {
$value = $payload[$meta->getExportName()];
$type = $this->getPropertyType($meta, $context);
} catch (\Throwable) {
return false;
}

// Assert valid type
if (!$type->match($value, $context)) {
return false;
}
}

return true;
}

/**
Expand Down Expand Up @@ -165,10 +215,7 @@ private function denormalizeObject(array $value, object $object, Context $contex
// In case of value has been passed
case \array_key_exists($meta->getExportName(), $value):
$element = $value[$meta->getExportName()];

// Fetch field type
$info = $meta->findTypeInfo();
$type = $info !== null ? $info->getType() : $context->getTypeByDefinition('mixed');
$type = $this->getPropertyType($meta, $context);

try {
$element = $type->cast($element, $entrance);
Expand Down

0 comments on commit fb412ca

Please sign in to comment.