Skip to content

Commit

Permalink
refactor: Mover more logic to TransformerRegistry.
Browse files Browse the repository at this point in the history
  • Loading branch information
priyadi committed Jan 13, 2024
1 parent bdf1494 commit d6feb05
Show file tree
Hide file tree
Showing 25 changed files with 199 additions and 80 deletions.
4 changes: 2 additions & 2 deletions src/Contracts/MainTransformerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
interface MainTransformerInterface
{
/**
* @param array<array-key,Type> $targetType If provided, it will be used instead of guessing the type
* @param array<array-key,Type> $targetTypes If provided, it will be used instead of guessing the type
* @param array<string,mixed> $context
*/
public function transform(
mixed $source,
mixed $target,
array $targetType,
array $targetTypes,
array $context
): mixed;
}
2 changes: 1 addition & 1 deletion src/Contracts/TransformerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ interface TransformerInterface
public function transform(
mixed $source,
mixed $target,
Type $sourceType,
?Type $sourceType,
?Type $targetType,
array $context
): mixed;
Expand Down
7 changes: 6 additions & 1 deletion src/Exception/MissingMemberKeyTypeException.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,18 @@

namespace Rekalogika\Mapper\Exception;

use Rekalogika\Mapper\Contracts\MixedType;
use Rekalogika\Mapper\Util\TypeUtil;
use Symfony\Component\PropertyInfo\Type;

class MissingMemberKeyTypeException extends MissingMemberTypeException
{
public function __construct(Type $sourceType, Type $targetType)
public function __construct(?Type $sourceType, Type $targetType)
{
if (null === $sourceType) {
$sourceType = MixedType::instance();
}

parent::__construct(sprintf('Trying to map collection type "%s" to "%s", but the source member key is not the simple array-key type, and the target does not have the type information about the key of its child members. Usually you can fix this by adding a PHPdoc to the property containing the collection type.', TypeUtil::getDebugType($sourceType), TypeUtil::getDebugType($targetType)));
}
}
7 changes: 6 additions & 1 deletion src/Exception/MissingMemberValueTypeException.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,18 @@

namespace Rekalogika\Mapper\Exception;

use Rekalogika\Mapper\Contracts\MixedType;
use Rekalogika\Mapper\Util\TypeUtil;
use Symfony\Component\PropertyInfo\Type;

class MissingMemberValueTypeException extends MissingMemberTypeException
{
public function __construct(Type $sourceType, Type $targetType)
public function __construct(?Type $sourceType, Type $targetType)
{
if (null === $sourceType) {
$sourceType = MixedType::instance();
}

parent::__construct(sprintf('Trying to map collection type "%s" to "%s", but the target does not have the type information about the value of its child members. Usually you can fix this by adding a PHPdoc to the property containing the collection type.', TypeUtil::getDebugType($sourceType), TypeUtil::getDebugType($targetType)));
}
}
15 changes: 6 additions & 9 deletions src/Exception/UnableToFindSuitableTransformerException.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,14 @@
class UnableToFindSuitableTransformerException extends NotMappableValueException
{
/**
* @param Type $sourceType
* @param Type|array<array-key,Type|MixedType> $targetType
* @param array<array-key,Type|MixedType> $sourceTypes
* @param array<array-key,Type|MixedType> $targetTypes
*/
public function __construct(Type $sourceType, Type|MixedType|array $targetType)
public function __construct(array $sourceTypes, array $targetTypes)
{
if (is_array($targetType)) {
$targetType = implode(', ', array_map(fn (Type|MixedType $type) => TypeUtil::getDebugType($type), $targetType));
} else {
$targetType = TypeUtil::getDebugType($targetType);
}
$sourceTypes = TypeUtil::getDebugType($sourceTypes);
$targetTypes = TypeUtil::getDebugType($targetTypes);

parent::__construct(sprintf('Unable to map the value "%s" to "%s"', TypeUtil::getDebugType($sourceType), $targetType));
parent::__construct(sprintf('Unable to find a suitable transformer for mapping the source types "%s" to the target types "%s"', $sourceTypes, $sourceTypes));
}
}
51 changes: 29 additions & 22 deletions src/MainTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,17 @@ public static function getObjectCache(
public function transform(
mixed $source,
mixed $target,
array $targetType,
array $targetTypes,
array $context
): mixed {
// if targettype is not provided, guess it from target
// if the target is also missing then the target is mixed

if (count($targetType) === 0) {
if (count($targetTypes) === 0) {
if ($target === null) {
$targetType = [MixedType::instance()];
$targetTypes = [MixedType::instance()];
} else {
$targetType = [$this->typeResolver->guessTypeFromVariable($target)];
$targetTypes = [$this->typeResolver->guessTypeFromVariable($target)];
}
}

Expand All @@ -99,8 +99,8 @@ public function transform(

$simpleTargetTypes = [];

foreach ($targetType as $singleTargetType) {
foreach ($this->typeResolver->getSimpleTypes($singleTargetType) as $simpleType) {
foreach ($targetTypes as $targetType) {
foreach ($this->typeResolver->getSimpleTypes($targetType) as $simpleType) {
$simpleTargetTypes[] = $simpleType;
}
}
Expand All @@ -111,26 +111,33 @@ public function transform(

// iterate simple target types and find the suitable transformer

foreach ($simpleTargetTypes as $singleTargetType) {
$transformers = $this->transformerRegistry
->findBySourceAndTargetType($sourceType, $singleTargetType);
$searchResult = $this->transformerRegistry
->findBySourceAndTargetTypes(
[$sourceType],
$simpleTargetTypes
);

foreach ($transformers as $transformer) {
$transformer = $this->processTransformer($transformer);
foreach ($searchResult as $searchEntry) {
$transformer = $this->processTransformer($searchEntry->getTransformer());

/** @var mixed */
$result = $transformer->transform(
source: $source,
target: $target,
sourceType: $sourceType,
targetType: $singleTargetType instanceof MixedType ? null : $singleTargetType,
context: $context
);
$sourceType = $searchEntry->getSourceType();
$sourceTypeForTransformer = $sourceType instanceof MixedType ? null : $sourceType;

return $result;
}
$targetTypes = $searchEntry->getTargetType();
$targetTypeForTransformer = $targetTypes instanceof MixedType ? null : $targetTypes;

/** @var mixed */
$result = $transformer->transform(
source: $source,
target: $target,
sourceType: $sourceTypeForTransformer,
targetType: $targetTypeForTransformer,
context: $context
);

return $result;
}

throw new UnableToFindSuitableTransformerException($sourceType, $targetType);
throw new UnableToFindSuitableTransformerException([$sourceType], $simpleTargetTypes);
}
}
2 changes: 1 addition & 1 deletion src/Mapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function map(mixed $source, object|string $target, array $context = []):
$target = $this->transformer->transform(
source: $source,
target: $target,
targetType: [$targetType],
targetTypes: [$targetType],
context: $context
);

Expand Down
2 changes: 1 addition & 1 deletion src/MethodMapper/ClassMethodTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function __construct(
public function transform(
mixed $source,
mixed $target,
Type $sourceType,
?Type $sourceType,
?Type $targetType,
array $context
): mixed {
Expand Down
2 changes: 1 addition & 1 deletion src/Transformer/ArrayToObjectTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function __construct(
public function transform(
mixed $source,
mixed $target,
Type $sourceType,
?Type $sourceType,
?Type $targetType,
array $context
): mixed {
Expand Down
2 changes: 1 addition & 1 deletion src/Transformer/CopyTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ final class CopyTransformer implements TransformerInterface
public function transform(
mixed $source,
mixed $target,
Type $sourceType,
?Type $sourceType,
?Type $targetType,
array $context
): mixed {
Expand Down
2 changes: 1 addition & 1 deletion src/Transformer/DateTimeTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ final class DateTimeTransformer implements TransformerInterface
public function transform(
mixed $source,
mixed $target,
Type $sourceType,
?Type $sourceType,
?Type $targetType,
array $context
): mixed {
Expand Down
2 changes: 1 addition & 1 deletion src/Transformer/NullTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class NullTransformer implements TransformerInterface
public function transform(
mixed $source,
mixed $target,
Type $sourceType,
?Type $sourceType,
?Type $targetType,
array $context
): mixed {
Expand Down
2 changes: 1 addition & 1 deletion src/Transformer/ObjectToArrayTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function __construct(
public function transform(
mixed $source,
mixed $target,
Type $sourceType,
?Type $sourceType,
?Type $targetType,
array $context
): mixed {
Expand Down
4 changes: 2 additions & 2 deletions src/Transformer/ObjectToObjectTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public function __construct(
public function transform(
mixed $source,
mixed $target,
Type $sourceType,
?Type $sourceType,
?Type $targetType,
array $context
): mixed {
Expand Down Expand Up @@ -169,7 +169,7 @@ private function resolveTargetPropertyValue(
$targetPropertyValue = $this->mainTransformer?->transform(
source: $sourcePropertyValue,
target: $targetPropertyValue,
targetType: $targetPropertyTypes,
targetTypes: $targetPropertyTypes,
context: $context
);

Expand Down
2 changes: 1 addition & 1 deletion src/Transformer/ObjectToStringTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ final class ObjectToStringTransformer implements TransformerInterface
public function transform(
mixed $source,
mixed $target,
Type $sourceType,
?Type $sourceType,
?Type $targetType,
array $context
): mixed {
Expand Down
2 changes: 1 addition & 1 deletion src/Transformer/ScalarToScalarTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class ScalarToScalarTransformer implements TransformerInterface
public function transform(
mixed $source,
mixed $target,
Type $sourceType,
?Type $sourceType,
?Type $targetType,
array $context
): mixed {
Expand Down
2 changes: 1 addition & 1 deletion src/Transformer/StringToBackedEnumTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ final class StringToBackedEnumTransformer implements TransformerInterface
public function transform(
mixed $source,
mixed $target,
Type $sourceType,
?Type $sourceType,
?Type $targetType,
array $context
): mixed {
Expand Down
6 changes: 3 additions & 3 deletions src/Transformer/TraversableToArrayAccessTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function __construct(
public function transform(
mixed $source,
mixed $target,
Type $sourceType,
?Type $sourceType,
?Type $targetType,
array $context
): mixed {
Expand Down Expand Up @@ -121,7 +121,7 @@ public function transform(
$targetMemberKey = $this->getMainTransformer()->transform(
source: $sourceMemberKey,
target: null,
targetType: $targetMemberKeyType,
targetTypes: $targetMemberKeyType,
context: $context,
);
}
Expand All @@ -145,7 +145,7 @@ public function transform(
$targetMemberValue = $this->getMainTransformer()->transform(
source: $sourceMemberValue,
target: $targetMemberValue,
targetType: $targetMemberValueType,
targetTypes: $targetMemberValueType,
context: $context,
);

Expand Down
6 changes: 3 additions & 3 deletions src/Transformer/TraversableToTraversableTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function __construct(
public function transform(
mixed $source,
mixed $target,
Type $sourceType,
?Type $sourceType,
?Type $targetType,
array $context
): mixed {
Expand Down Expand Up @@ -132,7 +132,7 @@ public function transform(
$targetPropertyKey = $this->getMainTransformer()->transform(
source: $sourcePropertyKey,
target: null,
targetType: $targetMemberKeyType,
targetTypes: $targetMemberKeyType,
context: $context,
);
}
Expand All @@ -144,7 +144,7 @@ public function transform(
$targetPropertyValue = $this->getMainTransformer()->transform(
source: $sourcePropertyValue,
target: null,
targetType: $targetMemberValueType,
targetTypes: $targetMemberValueType,
context: $context,
);

Expand Down
33 changes: 33 additions & 0 deletions src/TransformerRegistry/SearchResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\TransformerRegistry;

/**
* @implements \IteratorAggregate<int,SearchResultEntry>
*/
class SearchResult implements \IteratorAggregate
{
/**
* @param \Traversable<int,SearchResultEntry> $entries
*/
public function __construct(
private \Traversable $entries
) {
}

public function getIterator(): \Traversable
{
return $this->entries;
}
}
Loading

0 comments on commit d6feb05

Please sign in to comment.