From 560ae69682b90e01656570f9deed34d65099adf9 Mon Sep 17 00:00:00 2001 From: Priyadi Iman Nurcahyo <1102197+priyadi@users.noreply.github.com> Date: Sun, 14 Jan 2024 15:02:44 +0700 Subject: [PATCH] feat: If a transformer throws `RefuseToHandleException`, the `MainTransformer` will try the next suitable transformer. --- CHANGELOG.md | 2 ++ src/MainTransformer/MainTransformer.php | 22 +++++++++------- src/Transformer/CopyTransformer.php | 11 +++++++- .../Exception/RefuseToHandleException.php | 25 +++++++++++++++++++ 4 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 src/Transformer/Exception/RefuseToHandleException.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a70d016..bb77d2e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ exceptions. * feat: Main transformer's exception now accepts `$context` variable. * feat: More useful `TransformerReturnsUnexpectedValueException` exception message. +* feat: If a transformer throws `RefuseToHandleException`, the `MainTransformer` + will try the next suitable transformer. ## 0.5.8 diff --git a/src/MainTransformer/MainTransformer.php b/src/MainTransformer/MainTransformer.php index 4d46096d..8edd153c 100644 --- a/src/MainTransformer/MainTransformer.php +++ b/src/MainTransformer/MainTransformer.php @@ -24,6 +24,7 @@ use Rekalogika\Mapper\Transformer\Contracts\MainTransformerAwareInterface; use Rekalogika\Mapper\Transformer\Contracts\MixedType; use Rekalogika\Mapper\Transformer\Contracts\TransformerInterface; +use Rekalogika\Mapper\Transformer\Exception\RefuseToHandleException; use Rekalogika\Mapper\TransformerRegistry\TransformerRegistryInterface; use Rekalogika\Mapper\TypeResolver\TypeResolverInterface; use Rekalogika\Mapper\Util\TypeCheck; @@ -163,20 +164,23 @@ public function transform( // transform the source to the target - /** @var mixed */ - $result = $transformer->transform( - source: $source, - target: $target, - sourceType: $sourceTypeForTransformer, - targetType: $targetTypeForTransformer, - context: $context - ); + try { + /** @var mixed */ + $result = $transformer->transform( + source: $source, + target: $target, + sourceType: $sourceTypeForTransformer, + targetType: $targetTypeForTransformer, + context: $context + ); + } catch (RefuseToHandleException) { + continue; + } // check the result type if ( !TypeCheck::isVariableInstanceOf($result, $targetType) - && $result !== null ) { throw new TransformerReturnsUnexpectedValueException($source, $targetType, $result, $transformer, $context); } diff --git a/src/Transformer/CopyTransformer.php b/src/Transformer/CopyTransformer.php index aa0d5b4e..a4def39a 100644 --- a/src/Transformer/CopyTransformer.php +++ b/src/Transformer/CopyTransformer.php @@ -17,6 +17,8 @@ use Rekalogika\Mapper\Transformer\Contracts\MixedType; use Rekalogika\Mapper\Transformer\Contracts\TransformerInterface; use Rekalogika\Mapper\Transformer\Contracts\TypeMapping; +use Rekalogika\Mapper\Transformer\Exception\RefuseToHandleException; +use Rekalogika\Mapper\Util\TypeCheck; use Symfony\Component\PropertyInfo\Type; final class CopyTransformer implements TransformerInterface @@ -37,7 +39,14 @@ public function transform( if (!$clonable) { return $source; } - return clone $source; + + $result = clone $source; + + if ($targetType !== null && !TypeCheck::isVariableInstanceOf($result, $targetType)) { + throw new RefuseToHandleException(); + } + + return $result; } public function getSupportedTransformation(): iterable diff --git a/src/Transformer/Exception/RefuseToHandleException.php b/src/Transformer/Exception/RefuseToHandleException.php new file mode 100644 index 00000000..0d3e08b7 --- /dev/null +++ b/src/Transformer/Exception/RefuseToHandleException.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +namespace Rekalogika\Mapper\Transformer\Exception; + +use Rekalogika\Mapper\Exception\RuntimeException; + +/** + * If a transformer throw this exception, it means that the transformer is not + * able to handle the given source type in an ad-hoc basis. The main transformer + * will try the next transformer for the task. + */ +class RefuseToHandleException extends RuntimeException +{ +}