diff --git a/src/Compiler/Mapper/Array/MapArray.php b/src/Compiler/Mapper/Array/MapArray.php index 4cc2370..1134a36 100644 --- a/src/Compiler/Mapper/Array/MapArray.php +++ b/src/Compiler/Mapper/Array/MapArray.php @@ -24,13 +24,13 @@ public function __construct( { } - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { [$keyVariableName, $valueVariableName, $mappedVariableName] = $builder->uniqVariableNames('key', 'value', 'mapped'); - $itemPath = $builder->arrayImmutableAppend($path, $builder->var($keyVariableName)); - $itemKeyMapper = $this->keyMapperCompiler->compile($builder->var($keyVariableName), $itemPath, $builder); - $itemValueMapper = $this->valueMapperCompiler->compile($builder->var($valueVariableName), $itemPath, $builder); + $itemContext = $builder->mapperContextAppend($context, $builder->var($keyVariableName)); + $itemKeyMapper = $this->keyMapperCompiler->compile($builder->var($keyVariableName), $itemContext, $builder); + $itemValueMapper = $this->valueMapperCompiler->compile($builder->var($valueVariableName), $itemContext, $builder); $statements = [ $builder->if($builder->not($builder->funcCall($builder->importFunction('is_array'), [$value])), [ @@ -38,7 +38,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectType', - [$value, $path, $builder->val('array')], + [$value, $context, $builder->val('array')], ), ), ]), diff --git a/src/Compiler/Mapper/Array/MapArrayShape.php b/src/Compiler/Mapper/Array/MapArrayShape.php index 232ad6f..3ccf100 100644 --- a/src/Compiler/Mapper/Array/MapArrayShape.php +++ b/src/Compiler/Mapper/Array/MapArrayShape.php @@ -33,7 +33,7 @@ public function __construct( { } - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { $statements = []; $mappedVariableName = $builder->uniqVariableName('mapped'); @@ -44,7 +44,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectType', - [$value, $path, $builder->val('array')], + [$value, $context, $builder->val('array')], ), ), ]); @@ -56,14 +56,14 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $isMissing = $builder->not($isPresent); $itemValue = $builder->arrayDimFetch($value, $builder->val($itemMapping->key)); - $itemPath = $builder->arrayImmutableAppend($path, $builder->val($itemMapping->key)); + $itemContext = $builder->mapperContextAppend($context, $builder->val($itemMapping->key)); $itemMapperMethodName = $builder->uniqMethodName('map' . ucfirst($itemMapping->key)); $itemMapperMethod = $builder->mapperMethod($itemMapperMethodName, $itemMapping->mapper)->makePrivate()->getNode(); $builder->addMethod($itemMapperMethod); $itemAssignment = $builder->assign( $builder->arrayDimFetch($builder->var($mappedVariableName), $builder->val($itemMapping->key)), - $builder->methodCall($builder->var('this'), $itemMapperMethodName, [$itemValue, $itemPath]), + $builder->methodCall($builder->var('this'), $itemMapperMethodName, [$itemValue, $itemContext]), ); if ($itemMapping->optional) { @@ -75,7 +75,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $builder->staticCall( $builder->importClass(MappingFailedException::class), 'missingKey', - [$path, $builder->val($itemMapping->key)], + [$context, $builder->val($itemMapping->key)], ), ), ]); @@ -85,7 +85,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi } if ($this->sealed) { - array_push($statements, ...$this->checkForExtraKeys($value, $path, $builder)); + array_push($statements, ...$this->checkForExtraKeys($value, $context, $builder)); } return new CompiledExpr($builder->var($mappedVariableName), $statements); @@ -114,7 +114,7 @@ public function getOutputType(): TypeNode /** * @return list */ - private function checkForExtraKeys(Expr $value, Expr $path, PhpCodeBuilder $builder): array + private function checkForExtraKeys(Expr $value, Expr $context, PhpCodeBuilder $builder): array { $statements = []; @@ -131,7 +131,7 @@ private function checkForExtraKeys(Expr $value, Expr $path, PhpCodeBuilder $buil $builder->staticCall( $builder->importClass(MappingFailedException::class), 'extraKeys', - [$path, $builder->funcCall($builder->importFunction('array_keys'), [$builder->var($extraKeysVariableName)])], + [$context, $builder->funcCall($builder->importFunction('array_keys'), [$builder->var($extraKeysVariableName)])], ), ), ]); diff --git a/src/Compiler/Mapper/Array/MapList.php b/src/Compiler/Mapper/Array/MapList.php index 5837e8c..17849b1 100644 --- a/src/Compiler/Mapper/Array/MapList.php +++ b/src/Compiler/Mapper/Array/MapList.php @@ -22,13 +22,13 @@ public function __construct( { } - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { [$indexVariableName, $itemVariableName, $mappedVariableName] = $builder->uniqVariableNames('index', 'item', 'mapped'); $itemValue = $builder->var($itemVariableName); - $itemPath = $builder->arrayImmutableAppend($path, $builder->var($indexVariableName)); - $itemMapper = $this->itemMapperCompiler->compile($itemValue, $itemPath, $builder); + $itemContext = $builder->mapperContextAppend($context, $builder->var($indexVariableName)); + $itemMapper = $this->itemMapperCompiler->compile($itemValue, $itemContext, $builder); $isArray = $builder->funcCall($builder->importFunction('is_array'), [$value]); $isList = $builder->funcCall($builder->importFunction('array_is_list'), [$value]); @@ -39,7 +39,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectType', - [$value, $path, $builder->val('list')], + [$value, $context, $builder->val('list')], ), ), ]), diff --git a/src/Compiler/Mapper/MapRuntime.php b/src/Compiler/Mapper/MapRuntime.php index 6887442..4419780 100644 --- a/src/Compiler/Mapper/MapRuntime.php +++ b/src/Compiler/Mapper/MapRuntime.php @@ -6,19 +6,19 @@ use ShipMonk\InputMapper\Compiler\CompiledExpr; use ShipMonk\InputMapper\Compiler\Php\PhpCodeBuilder; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; +use ShipMonk\InputMapper\Runtime\MapperContext; abstract class MapRuntime implements MapperCompiler { /** - * @param list $path * @throws MappingFailedException */ - abstract public static function mapValue(mixed $value, array $path): mixed; + abstract public static function mapValue(mixed $value, ?MapperContext $context): mixed; public function compile( Expr $value, - Expr $path, + Expr $context, PhpCodeBuilder $builder, ): CompiledExpr { @@ -26,7 +26,7 @@ public function compile( $builder->staticCall( $builder->importClass(static::class), 'mapValue', - [$value, $path], + [$value, $context], ), ); } diff --git a/src/Compiler/Mapper/MapperCompiler.php b/src/Compiler/Mapper/MapperCompiler.php index f45408b..b20b973 100644 --- a/src/Compiler/Mapper/MapperCompiler.php +++ b/src/Compiler/Mapper/MapperCompiler.php @@ -14,7 +14,7 @@ interface MapperCompiler /** * @throws CannotCompileMapperException */ - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr; + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr; public function getInputType(): TypeNode; diff --git a/src/Compiler/Mapper/Mixed/MapMixed.php b/src/Compiler/Mapper/Mixed/MapMixed.php index 85e40a0..afc5c9b 100644 --- a/src/Compiler/Mapper/Mixed/MapMixed.php +++ b/src/Compiler/Mapper/Mixed/MapMixed.php @@ -14,7 +14,7 @@ class MapMixed implements MapperCompiler { - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { return new CompiledExpr($value); } diff --git a/src/Compiler/Mapper/Object/DelegateMapperCompiler.php b/src/Compiler/Mapper/Object/DelegateMapperCompiler.php index 1f32035..32c83e8 100644 --- a/src/Compiler/Mapper/Object/DelegateMapperCompiler.php +++ b/src/Compiler/Mapper/Object/DelegateMapperCompiler.php @@ -21,12 +21,12 @@ public function __construct( { } - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { $shortName = $builder->importClass($this->className); $provider = $builder->propertyFetch($builder->var('this'), 'provider'); $mapper = $builder->methodCall($provider, 'get', [$builder->classConstFetch($shortName, 'class')]); - $mapped = $builder->methodCall($mapper, 'map', [$value, $path]); + $mapped = $builder->methodCall($mapper, 'map', [$value, $context]); return new CompiledExpr($mapped); } diff --git a/src/Compiler/Mapper/Object/MapDateTimeImmutable.php b/src/Compiler/Mapper/Object/MapDateTimeImmutable.php index 71e1320..4dda8e5 100644 --- a/src/Compiler/Mapper/Object/MapDateTimeImmutable.php +++ b/src/Compiler/Mapper/Object/MapDateTimeImmutable.php @@ -35,7 +35,7 @@ public function __construct( { } - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { $mappedVariableName = $builder->uniqVariableName('mapped'); $timezoneVariableName = $builder->uniqVariableName('timezone'); @@ -60,7 +60,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectType', - [$value, $path, $builder->val('string')], + [$value, $context, $builder->val('string')], ), ), ]), @@ -97,7 +97,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $this->formatDescription], + [$value, $context, $this->formatDescription], ), ), ]); diff --git a/src/Compiler/Mapper/Object/MapEnum.php b/src/Compiler/Mapper/Object/MapEnum.php index 8e1de29..bcc496d 100644 --- a/src/Compiler/Mapper/Object/MapEnum.php +++ b/src/Compiler/Mapper/Object/MapEnum.php @@ -26,9 +26,9 @@ public function __construct( { } - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { - $backingValueMapper = $this->backingValueMapperCompiler->compile($value, $path, $builder); + $backingValueMapper = $this->backingValueMapperCompiler->compile($value, $context, $builder); $statements = $backingValueMapper->statements; $enumOrNull = $builder->staticCall($builder->importClass($this->enumName), 'tryFrom', [$backingValueMapper->expr]); @@ -51,7 +51,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $expectedDescription], + [$value, $context, $expectedDescription], ), ), ]); diff --git a/src/Compiler/Mapper/Object/MapObject.php b/src/Compiler/Mapper/Object/MapObject.php index 980aec8..1094415 100644 --- a/src/Compiler/Mapper/Object/MapObject.php +++ b/src/Compiler/Mapper/Object/MapObject.php @@ -37,7 +37,7 @@ public function __construct( { } - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { $statements = [ $builder->if($builder->not($builder->funcCall($builder->importFunction('is_array'), [$value])), [ @@ -45,7 +45,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectType', - [$value, $path, $builder->val('array')], + [$value, $context, $builder->val('array')], ), ), ]), @@ -58,15 +58,15 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $isMissing = $builder->not($isPresent); $propertyValue = $builder->arrayDimFetch($value, $builder->val($key)); - $propertyPath = $builder->arrayImmutableAppend($path, $builder->val($key)); + $propertyContext = $builder->mapperContextAppend($context, $builder->val($key)); $propertyMapperMethodName = $builder->uniqMethodName('map' . ucfirst($key)); $propertyMapperMethod = $builder->mapperMethod($propertyMapperMethodName, $argMapperCompiler)->makePrivate()->getNode(); - $propertyMapperCall = $builder->methodCall($builder->var('this'), $propertyMapperMethodName, [$propertyValue, $propertyPath]); + $propertyMapperCall = $builder->methodCall($builder->var('this'), $propertyMapperMethodName, [$propertyValue, $propertyContext]); $builder->addMethod($propertyMapperMethod); if ($argMapperCompiler instanceof UndefinedAwareMapperCompiler) { $propertyValueVarName = $builder->uniqVariableName($key); - $fallbackValueMapper = $argMapperCompiler->compileUndefined($path, $builder->val($key), $builder); + $fallbackValueMapper = $argMapperCompiler->compileUndefined($context, $builder->val($key), $builder); if (count($fallbackValueMapper->statements) > 0) { $statements[] = $builder->if( @@ -88,7 +88,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $builder->staticCall( $builder->importClass(MappingFailedException::class), 'missingKey', - [$path, $key], + [$context, $key], ), ), ]); @@ -98,7 +98,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi } if (!$this->allowExtraKeys) { - array_push($statements, ...$this->checkForExtraKeys($value, $path, $builder)); + array_push($statements, ...$this->checkForExtraKeys($value, $context, $builder)); } return new CompiledExpr( @@ -120,7 +120,7 @@ public function getOutputType(): TypeNode /** * @return list */ - private function checkForExtraKeys(Expr $value, Expr $path, PhpCodeBuilder $builder): array + private function checkForExtraKeys(Expr $value, Expr $context, PhpCodeBuilder $builder): array { $statements = []; @@ -137,7 +137,7 @@ private function checkForExtraKeys(Expr $value, Expr $path, PhpCodeBuilder $buil $builder->staticCall( $builder->importClass(MappingFailedException::class), 'extraKeys', - [$path, $builder->funcCall($builder->importFunction('array_keys'), [$builder->var($extraKeysVariableName)])], + [$context, $builder->funcCall($builder->importFunction('array_keys'), [$builder->var($extraKeysVariableName)])], ), ), ]); diff --git a/src/Compiler/Mapper/Scalar/MapBool.php b/src/Compiler/Mapper/Scalar/MapBool.php index 2b7c5c8..b7229fe 100644 --- a/src/Compiler/Mapper/Scalar/MapBool.php +++ b/src/Compiler/Mapper/Scalar/MapBool.php @@ -15,7 +15,7 @@ class MapBool implements MapperCompiler { - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { $statements = [ $builder->if($builder->not($builder->funcCall($builder->importFunction('is_bool'), [$value])), [ @@ -23,7 +23,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectType', - [$value, $path, $builder->val('bool')], + [$value, $context, $builder->val('bool')], ), ), ]), diff --git a/src/Compiler/Mapper/Scalar/MapFloat.php b/src/Compiler/Mapper/Scalar/MapFloat.php index a9813d2..ef51058 100644 --- a/src/Compiler/Mapper/Scalar/MapFloat.php +++ b/src/Compiler/Mapper/Scalar/MapFloat.php @@ -33,7 +33,7 @@ public function __construct( { } - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { $mappedVariableName = $builder->uniqVariableName('mapped'); @@ -44,14 +44,14 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $builder->if( if: $isFloat, then: [ - ...$this->createFiniteCheckStatements($value, $path, $builder), + ...$this->createFiniteCheckStatements($value, $context, $builder), $builder->assign($builder->var($mappedVariableName), $value), ], else: [ $builder->if( if: $isInt, then: [ - ...$this->createSafeIntCheckStatements($value, $path, $builder), + ...$this->createSafeIntCheckStatements($value, $context, $builder), $builder->assign($builder->var($mappedVariableName), $builder->funcCall($builder->importFunction('floatval'), [$value])), ], else: [ @@ -59,7 +59,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectType', - [$value, $path, 'float'], + [$value, $context, 'float'], ), ), ], @@ -84,7 +84,7 @@ public function getOutputType(): TypeNode /** * @return list */ - private function createFiniteCheckStatements(Expr $value, Expr $path, PhpCodeBuilder $builder): array + private function createFiniteCheckStatements(Expr $value, Expr $context, PhpCodeBuilder $builder): array { if (!$this->allowInfinity && !$this->allowNan) { $finiteCheck = $builder->not($builder->funcCall($builder->importFunction('is_finite'), [$value])); @@ -108,7 +108,7 @@ private function createFiniteCheckStatements(Expr $value, Expr $path, PhpCodeBui $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectType', - [$value, $path, $finiteLabel], + [$value, $context, $finiteLabel], ), ), ]), @@ -118,7 +118,7 @@ private function createFiniteCheckStatements(Expr $value, Expr $path, PhpCodeBui /** * @return list */ - private function createSafeIntCheckStatements(Expr $value, Expr $path, PhpCodeBuilder $builder): array + private function createSafeIntCheckStatements(Expr $value, Expr $context, PhpCodeBuilder $builder): array { $minSafeIntConstName = $builder->uniqConstantName('MIN_SAFE_INTEGER', self::MIN_SAFE_INTEGER); $maxSafeIntConstName = $builder->uniqConstantName('MAX_SAFE_INTEGER', self::MAX_SAFE_INTEGER); @@ -137,7 +137,7 @@ private function createSafeIntCheckStatements(Expr $value, Expr $path, PhpCodeBu $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, 'float or int with value that can be losslessly converted to float'], + [$value, $context, 'float or int with value that can be losslessly converted to float'], ), ), ]), diff --git a/src/Compiler/Mapper/Scalar/MapInt.php b/src/Compiler/Mapper/Scalar/MapInt.php index e7361b9..46cc5fb 100644 --- a/src/Compiler/Mapper/Scalar/MapInt.php +++ b/src/Compiler/Mapper/Scalar/MapInt.php @@ -15,7 +15,7 @@ class MapInt implements MapperCompiler { - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { $statements = [ $builder->if($builder->not($builder->funcCall($builder->importFunction('is_int'), [$value])), [ @@ -23,7 +23,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectType', - [$value, $path, $builder->val('int')], + [$value, $context, $builder->val('int')], ), ), ]), diff --git a/src/Compiler/Mapper/Scalar/MapString.php b/src/Compiler/Mapper/Scalar/MapString.php index 6ae0cdd..5a65f8c 100644 --- a/src/Compiler/Mapper/Scalar/MapString.php +++ b/src/Compiler/Mapper/Scalar/MapString.php @@ -15,7 +15,7 @@ class MapString implements MapperCompiler { - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { $statements = [ $builder->if($builder->not($builder->funcCall($builder->importFunction('is_string'), [$value])), [ @@ -23,7 +23,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectType', - [$value, $path, $builder->val('string')], + [$value, $context, $builder->val('string')], ), ), ]), diff --git a/src/Compiler/Mapper/UndefinedAwareMapperCompiler.php b/src/Compiler/Mapper/UndefinedAwareMapperCompiler.php index fd785d9..4336b09 100644 --- a/src/Compiler/Mapper/UndefinedAwareMapperCompiler.php +++ b/src/Compiler/Mapper/UndefinedAwareMapperCompiler.php @@ -9,6 +9,6 @@ interface UndefinedAwareMapperCompiler extends MapperCompiler { - public function compileUndefined(Expr $path, Expr $key, PhpCodeBuilder $builder): CompiledExpr; + public function compileUndefined(Expr $context, Expr $key, PhpCodeBuilder $builder): CompiledExpr; } diff --git a/src/Compiler/Mapper/Wrapper/ChainMapperCompiler.php b/src/Compiler/Mapper/Wrapper/ChainMapperCompiler.php index 82289ab..96a3b50 100644 --- a/src/Compiler/Mapper/Wrapper/ChainMapperCompiler.php +++ b/src/Compiler/Mapper/Wrapper/ChainMapperCompiler.php @@ -24,7 +24,7 @@ public function __construct( { } - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { $statements = []; $mappedVariableName = $builder->uniqVariableName('mapped'); @@ -38,7 +38,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi throw CannotCompileMapperException::withIncompatibleMapper($mapperCompiler, $mapperOutputType); } - $mapper = $mapperCompiler->compile($value, $path, $builder); + $mapper = $mapperCompiler->compile($value, $context, $builder); $mapperOutputType = $mapperCompiler->getOutputType(); foreach ($mapper->statements as $statement) { diff --git a/src/Compiler/Mapper/Wrapper/MapNullable.php b/src/Compiler/Mapper/Wrapper/MapNullable.php index b08287b..5475996 100644 --- a/src/Compiler/Mapper/Wrapper/MapNullable.php +++ b/src/Compiler/Mapper/Wrapper/MapNullable.php @@ -20,9 +20,9 @@ public function __construct( { } - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { - $mapper = $this->innerMapperCompiler->compile($value, $path, $builder); + $mapper = $this->innerMapperCompiler->compile($value, $context, $builder); $mappedVariableName = $builder->uniqVariableName('mapped'); $statements = [ diff --git a/src/Compiler/Mapper/Wrapper/MapOptional.php b/src/Compiler/Mapper/Wrapper/MapOptional.php index f16ec09..0b65b94 100644 --- a/src/Compiler/Mapper/Wrapper/MapOptional.php +++ b/src/Compiler/Mapper/Wrapper/MapOptional.php @@ -23,16 +23,16 @@ public function __construct( { } - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { - $mapper = $this->mapperCompiler->compile($value, $path, $builder); + $mapper = $this->mapperCompiler->compile($value, $context, $builder); $mapped = $builder->staticCall($builder->importClass(Optional::class), 'of', [$mapper->expr]); return new CompiledExpr($mapped, $mapper->statements); } - public function compileUndefined(Expr $path, Expr $key, PhpCodeBuilder $builder): CompiledExpr + public function compileUndefined(Expr $context, Expr $key, PhpCodeBuilder $builder): CompiledExpr { - $mapped = $builder->staticCall($builder->importClass(Optional::class), 'none', [$path, $key]); + $mapped = $builder->staticCall($builder->importClass(Optional::class), 'none', [$context, $key]); return new CompiledExpr($mapped); } diff --git a/src/Compiler/Mapper/Wrapper/ValidatedMapperCompiler.php b/src/Compiler/Mapper/Wrapper/ValidatedMapperCompiler.php index c1e392d..423c9c1 100644 --- a/src/Compiler/Mapper/Wrapper/ValidatedMapperCompiler.php +++ b/src/Compiler/Mapper/Wrapper/ValidatedMapperCompiler.php @@ -29,9 +29,9 @@ public function __construct( /** * @throws CannotCompileMapperException */ - public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): CompiledExpr + public function compile(Expr $value, Expr $context, PhpCodeBuilder $builder): CompiledExpr { - $mapper = $this->mapperCompiler->compile($value, $path, $builder); + $mapper = $this->mapperCompiler->compile($value, $context, $builder); $mapperOutputType = $this->mapperCompiler->getOutputType(); $statements = $mapper->statements; @@ -51,7 +51,7 @@ public function compile(Expr $value, Expr $path, PhpCodeBuilder $builder): Compi throw CannotCompileMapperException::withIncompatibleValidator($validatorCompiler, $this->mapperCompiler); } - foreach ($validatorCompiler->compile($mapperVariable, $mapperOutputType, $path, $builder) as $statement) { + foreach ($validatorCompiler->compile($mapperVariable, $mapperOutputType, $context, $builder) as $statement) { $statements[] = $statement; } } diff --git a/src/Compiler/Php/PhpCodeBuilder.php b/src/Compiler/Php/PhpCodeBuilder.php index 281f264..c089832 100644 --- a/src/Compiler/Php/PhpCodeBuilder.php +++ b/src/Compiler/Php/PhpCodeBuilder.php @@ -25,6 +25,7 @@ use PhpParser\Node\Expr\Instanceof_; use PhpParser\Node\Expr\Ternary; use PhpParser\Node\Name; +use PhpParser\Node\NullableType; use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\Class_ as ClassNode; use PhpParser\Node\Stmt\ClassConst; @@ -50,6 +51,7 @@ use ShipMonk\InputMapper\Compiler\Type\PhpDocTypeUtils; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function array_filter; use function array_pop; @@ -107,15 +109,6 @@ public function arrayItem(Expr $value, ?Expr $key): ArrayItem return new ArrayItem($value, $key); } - public function arrayImmutableAppend(Expr $path, Expr $item): Expr - { - if ($path instanceof Array_) { - return $this->array([...$path->items, new ArrayItem($this->val($item))]); - } - - return $this->array([new ArrayItem($path, unpack: true), new ArrayItem($this->val($item))]); - } - public function arrayDimFetch(Expr $var, ?Expr $dim = null): ArrayDimFetch { return new ArrayDimFetch($var, $dim); @@ -406,14 +399,19 @@ public function phpDoc(array $lines): string return "/**\n * " . implode("\n * ", $lines) . "\n */"; } + public function mapperContextAppend(Expr $context, Expr $key): Expr + { + return $this->staticCall($this->importClass(MapperContext::class), 'append', [$context, $key]); + } + public function mapperMethod(string $methodName, MapperCompiler $mapperCompiler): Method { - $mapper = $this->withVariableScope(function () use ($mapperCompiler, &$dataVarName, &$pathVarName): CompiledExpr { - [$dataVarName, $pathVarName] = $this->uniqVariableNames('data', 'path'); - return $mapperCompiler->compile($this->var($dataVarName), $this->var($pathVarName), $this); + $mapper = $this->withVariableScope(function () use ($mapperCompiler, &$dataVarName, &$contextVarName): CompiledExpr { + [$dataVarName, $contextVarName] = $this->uniqVariableNames('data', 'context'); + return $mapperCompiler->compile($this->var($dataVarName), $this->var($contextVarName), $this); }); - assert($dataVarName !== null && $pathVarName !== null); + assert($dataVarName !== null && $contextVarName !== null); $inputType = $mapperCompiler->getInputType(); $outputType = $mapperCompiler->getOutputType(); @@ -425,7 +423,6 @@ public function mapperMethod(string $methodName, MapperCompiler $mapperCompiler) $phpDoc = $this->phpDoc([ $phpDocInputTypeUseful ? "@param {$inputType} \${$dataVarName}" : null, - "@param list \${$pathVarName}", $phpDocOutputTypeUseful ? "@return {$outputType}" : null, '@throws ' . $this->importClass(MappingFailedException::class), ]); @@ -433,7 +430,7 @@ public function mapperMethod(string $methodName, MapperCompiler $mapperCompiler) return $this->method($methodName) ->setDocComment($phpDoc) ->addParam($this->param($dataVarName)->setType($nativeInputType)) - ->addParam($this->param($pathVarName)->setType('array')->setDefault($this->array([]))) + ->addParam($this->param($contextVarName)->setType(new NullableType(new Name($this->importClass(MapperContext::class))))->setDefault(null)) ->setReturnType($nativeOutputType) ->addStmts($mapper->statements) ->addStmt($this->return($mapper->expr)); diff --git a/src/Compiler/Validator/Array/AssertListItem.php b/src/Compiler/Validator/Array/AssertListItem.php index 337b50f..0977d0d 100644 --- a/src/Compiler/Validator/Array/AssertListItem.php +++ b/src/Compiler/Validator/Array/AssertListItem.php @@ -31,7 +31,7 @@ public function __construct( /** * @return list */ - public function compile(Expr $value, TypeNode $type, Expr $path, PhpCodeBuilder $builder): array + public function compile(Expr $value, TypeNode $type, Expr $context, PhpCodeBuilder $builder): array { [$itemVariableName, $indexVariableName] = $builder->uniqVariableNames('item', 'index'); $foreachBody = []; @@ -39,9 +39,9 @@ public function compile(Expr $value, TypeNode $type, Expr $path, PhpCodeBuilder foreach ($this->validators as $validator) { $itemValue = $builder->var($itemVariableName); $itemType = PhpDocTypeUtils::inferGenericParameter($type, 'list', 0); - $itemPath = $builder->arrayImmutableAppend($path, $builder->var($indexVariableName)); + $itemContext = $builder->mapperContextAppend($context, $builder->var($indexVariableName)); - foreach ($validator->compile($itemValue, $itemType, $itemPath, $builder) as $statement) { + foreach ($validator->compile($itemValue, $itemType, $itemContext, $builder) as $statement) { $foreachBody[] = $statement; } } diff --git a/src/Compiler/Validator/Array/AssertListLength.php b/src/Compiler/Validator/Array/AssertListLength.php index fe08a4f..582fd9e 100644 --- a/src/Compiler/Validator/Array/AssertListLength.php +++ b/src/Compiler/Validator/Array/AssertListLength.php @@ -38,7 +38,7 @@ public function __construct( /** * @return list */ - public function compile(Expr $value, TypeNode $type, Expr $path, PhpCodeBuilder $builder): array + public function compile(Expr $value, TypeNode $type, Expr $context, PhpCodeBuilder $builder): array { $statements = []; $length = $builder->funcCall($builder->importFunction('count'), [$value]); @@ -49,7 +49,7 @@ public function compile(Expr $value, TypeNode $type, Expr $path, PhpCodeBuilder $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("list with exactly {$this->min} items")], + [$value, $context, $builder->val("list with exactly {$this->min} items")], ), ), ]); @@ -61,7 +61,7 @@ public function compile(Expr $value, TypeNode $type, Expr $path, PhpCodeBuilder $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("list with at least {$this->min} items")], + [$value, $context, $builder->val("list with at least {$this->min} items")], ), ), ]); @@ -73,7 +73,7 @@ public function compile(Expr $value, TypeNode $type, Expr $path, PhpCodeBuilder $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("list with at most {$this->max} items")], + [$value, $context, $builder->val("list with at most {$this->max} items")], ), ), ]); diff --git a/src/Compiler/Validator/AssertRuntime.php b/src/Compiler/Validator/AssertRuntime.php index 541dc67..33a1bcf 100644 --- a/src/Compiler/Validator/AssertRuntime.php +++ b/src/Compiler/Validator/AssertRuntime.php @@ -9,15 +9,15 @@ use PHPStan\PhpDocParser\Ast\Type\TypeNode; use ShipMonk\InputMapper\Compiler\Php\PhpCodeBuilder; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; +use ShipMonk\InputMapper\Runtime\MapperContext; abstract class AssertRuntime implements ValidatorCompiler { /** - * @param list $path * @throws MappingFailedException */ - abstract public static function assertValue(mixed $value, array $path): void; + abstract public static function assertValue(mixed $value, ?MapperContext $context = null): void; /** * @return list @@ -25,7 +25,7 @@ abstract public static function assertValue(mixed $value, array $path): void; public function compile( Expr $value, TypeNode $type, - Expr $path, + Expr $context, PhpCodeBuilder $builder, ): array { @@ -34,7 +34,7 @@ public function compile( $builder->staticCall( $builder->importClass(static::class), 'assertValue', - [$value, $path], + [$value, $context], ), ), ]; diff --git a/src/Compiler/Validator/Float/AssertFloatMultipleOf.php b/src/Compiler/Validator/Float/AssertFloatMultipleOf.php index 5a4fddf..c3382bb 100644 --- a/src/Compiler/Validator/Float/AssertFloatMultipleOf.php +++ b/src/Compiler/Validator/Float/AssertFloatMultipleOf.php @@ -29,7 +29,7 @@ public function __construct( public function compile( Expr $value, TypeNode $type, - Expr $path, + Expr $context, PhpCodeBuilder $builder, ): array { @@ -43,7 +43,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("multiple of {$this->value}")], + [$value, $context, $builder->val("multiple of {$this->value}")], ), ), ]), diff --git a/src/Compiler/Validator/Float/AssertFloatRange.php b/src/Compiler/Validator/Float/AssertFloatRange.php index 486d1e3..48a211a 100644 --- a/src/Compiler/Validator/Float/AssertFloatRange.php +++ b/src/Compiler/Validator/Float/AssertFloatRange.php @@ -31,7 +31,7 @@ public function __construct( public function compile( Expr $value, TypeNode $type, - Expr $path, + Expr $context, PhpCodeBuilder $builder, ): array { @@ -43,7 +43,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("value greater than or equal to {$this->gte}")], + [$value, $context, $builder->val("value greater than or equal to {$this->gte}")], ), ), ]); @@ -55,7 +55,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("value greater than {$this->gt}")], + [$value, $context, $builder->val("value greater than {$this->gt}")], ), ), ]); @@ -67,7 +67,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("value less than {$this->lt}")], + [$value, $context, $builder->val("value less than {$this->lt}")], ), ), ]); @@ -79,7 +79,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("value less than or equal to {$this->lte}")], + [$value, $context, $builder->val("value less than or equal to {$this->lte}")], ), ), ]); diff --git a/src/Compiler/Validator/Int/AssertIntMultipleOf.php b/src/Compiler/Validator/Int/AssertIntMultipleOf.php index 7f17efc..6ca8e9f 100644 --- a/src/Compiler/Validator/Int/AssertIntMultipleOf.php +++ b/src/Compiler/Validator/Int/AssertIntMultipleOf.php @@ -28,7 +28,7 @@ public function __construct( public function compile( Expr $value, TypeNode $type, - Expr $path, + Expr $context, PhpCodeBuilder $builder, ): array { @@ -40,7 +40,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("multiple of {$this->value}")], + [$value, $context, $builder->val("multiple of {$this->value}")], ), ), ]), diff --git a/src/Compiler/Validator/Int/AssertIntRange.php b/src/Compiler/Validator/Int/AssertIntRange.php index 1d2bddf..3a02ccf 100644 --- a/src/Compiler/Validator/Int/AssertIntRange.php +++ b/src/Compiler/Validator/Int/AssertIntRange.php @@ -37,7 +37,7 @@ public function __construct( public function compile( Expr $value, TypeNode $type, - Expr $path, + Expr $context, PhpCodeBuilder $builder, ): array { @@ -49,7 +49,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("value greater than or equal to {$this->gte}")], + [$value, $context, $builder->val("value greater than or equal to {$this->gte}")], ), ), ]); @@ -61,7 +61,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("value greater than {$this->gt}")], + [$value, $context, $builder->val("value greater than {$this->gt}")], ), ), ]); @@ -73,7 +73,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("value less than {$this->lt}")], + [$value, $context, $builder->val("value less than {$this->lt}")], ), ), ]); @@ -85,7 +85,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("value less than or equal to {$this->lte}")], + [$value, $context, $builder->val("value less than or equal to {$this->lte}")], ), ), ]); diff --git a/src/Compiler/Validator/Object/AssertDateTimeRange.php b/src/Compiler/Validator/Object/AssertDateTimeRange.php index 483dad8..d81c7c4 100644 --- a/src/Compiler/Validator/Object/AssertDateTimeRange.php +++ b/src/Compiler/Validator/Object/AssertDateTimeRange.php @@ -36,7 +36,7 @@ public function __construct( public function compile( Expr $value, TypeNode $type, - Expr $path, + Expr $context, PhpCodeBuilder $builder, ): array { @@ -60,28 +60,28 @@ public function compile( if ($this->gte !== null) { $boundary = $builder->new($builder->importClass(DateTimeImmutable::class), [$builder->val($this->gte), ...$timezoneArgs]); $statements[] = $builder->if($builder->lt($value, $boundary), [ - $this->throwException('greater than or equal to', $this->gte, $value, $path, $builder), + $this->throwException('greater than or equal to', $this->gte, $value, $context, $builder), ]); } if ($this->gt !== null) { $boundary = $builder->new($builder->importClass(DateTimeImmutable::class), [$builder->val($this->gt), ...$timezoneArgs]); $statements[] = $builder->if($builder->lte($value, $boundary), [ - $this->throwException('greater than', $this->gt, $value, $path, $builder), + $this->throwException('greater than', $this->gt, $value, $context, $builder), ]); } if ($this->lt !== null) { $boundary = $builder->new($builder->importClass(DateTimeImmutable::class), [$builder->val($this->lt), ...$timezoneArgs]); $statements[] = $builder->if($builder->gte($value, $boundary), [ - $this->throwException('less than', $this->lt, $value, $path, $builder), + $this->throwException('less than', $this->lt, $value, $context, $builder), ]); } if ($this->lte !== null) { $boundary = $builder->new($builder->importClass(DateTimeImmutable::class), [$builder->val($this->lte), ...$timezoneArgs]); $statements[] = $builder->if($builder->gt($value, $boundary), [ - $this->throwException('less than or equal to', $this->lte, $value, $path, $builder), + $this->throwException('less than or equal to', $this->lte, $value, $context, $builder), ]); } @@ -99,7 +99,7 @@ private function throwException( string $boundaryDescription, string $boundaryValue, Expr $value, - Expr $path, + Expr $context, PhpCodeBuilder $builder, ): Throw_ { @@ -111,7 +111,7 @@ private function throwException( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("value {$boundaryDescription} {$boundaryValue}")], + [$value, $context, $builder->val("value {$boundaryDescription} {$boundaryValue}")], ), ); } diff --git a/src/Compiler/Validator/String/AssertStringLength.php b/src/Compiler/Validator/String/AssertStringLength.php index cc8ac7c..c41d95c 100644 --- a/src/Compiler/Validator/String/AssertStringLength.php +++ b/src/Compiler/Validator/String/AssertStringLength.php @@ -40,7 +40,7 @@ public function __construct( public function compile( Expr $value, TypeNode $type, - Expr $path, + Expr $context, PhpCodeBuilder $builder, ): array { @@ -53,7 +53,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("string with exactly {$this->min} characters")], + [$value, $context, $builder->val("string with exactly {$this->min} characters")], ), ), ]); @@ -65,7 +65,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("string with at least {$this->min} characters")], + [$value, $context, $builder->val("string with at least {$this->min} characters")], ), ), ]); @@ -77,7 +77,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val("string with at most {$this->max} characters")], + [$value, $context, $builder->val("string with at most {$this->max} characters")], ), ), ]); diff --git a/src/Compiler/Validator/String/AssertStringMatches.php b/src/Compiler/Validator/String/AssertStringMatches.php index 167d141..2548846 100644 --- a/src/Compiler/Validator/String/AssertStringMatches.php +++ b/src/Compiler/Validator/String/AssertStringMatches.php @@ -28,7 +28,7 @@ public function __construct( public function compile( Expr $value, TypeNode $type, - Expr $path, + Expr $context, PhpCodeBuilder $builder, ): array { @@ -40,7 +40,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val($this->expectedDescription ?? "string matching pattern {$this->pattern}")], + [$value, $context, $builder->val($this->expectedDescription ?? "string matching pattern {$this->pattern}")], ), ), ]), diff --git a/src/Compiler/Validator/String/AssertUrl.php b/src/Compiler/Validator/String/AssertUrl.php index 40cdb28..84eb567 100644 --- a/src/Compiler/Validator/String/AssertUrl.php +++ b/src/Compiler/Validator/String/AssertUrl.php @@ -22,7 +22,7 @@ class AssertUrl implements ValidatorCompiler public function compile( Expr $value, TypeNode $type, - Expr $path, + Expr $context, PhpCodeBuilder $builder, ): array { @@ -34,7 +34,7 @@ public function compile( $builder->staticCall( $builder->importClass(MappingFailedException::class), 'incorrectValue', - [$value, $path, $builder->val('valid URL')], + [$value, $context, $builder->val('valid URL')], ), ), ]), diff --git a/src/Compiler/Validator/ValidatorCompiler.php b/src/Compiler/Validator/ValidatorCompiler.php index f91e25a..222689c 100644 --- a/src/Compiler/Validator/ValidatorCompiler.php +++ b/src/Compiler/Validator/ValidatorCompiler.php @@ -16,7 +16,7 @@ interface ValidatorCompiler public function compile( Expr $value, TypeNode $type, - Expr $path, + Expr $context, PhpCodeBuilder $builder, ): array; diff --git a/src/Runtime/Exception/MappingFailedException.php b/src/Runtime/Exception/MappingFailedException.php index e7dd40c..300d883 100644 --- a/src/Runtime/Exception/MappingFailedException.php +++ b/src/Runtime/Exception/MappingFailedException.php @@ -3,6 +3,7 @@ namespace ShipMonk\InputMapper\Runtime\Exception; use DateTimeInterface; +use ShipMonk\InputMapper\Runtime\MapperContext; use Throwable; use function array_map; use function array_slice; @@ -31,72 +32,59 @@ class MappingFailedException extends RuntimeException private const JSON_ENCODE_OPTIONS = JSON_PRESERVE_ZERO_FRACTION | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR; private const MAX_STRING_LENGTH = 40; - /** - * @param list $path - */ - private function __construct(array $path, string $reason, ?Throwable $previous = null) + private function __construct(?MapperContext $context, string $reason, ?Throwable $previous = null) { - $jsonPointer = self::toJsonPointer($path); + $jsonPointer = self::toJsonPointer($context?->getPath() ?? []); parent::__construct("Failed to map data at path {$jsonPointer}: {$reason}", $previous); } - /** - * @param list $path - */ public static function incorrectType( mixed $data, - array $path, + ?MapperContext $context, string $expectedType, ?Throwable $previous = null ): self { $describedValue = self::describeValue($data); $reason = "Expected {$expectedType}, got {$describedValue}"; - return new self($path, $reason, $previous); + return new self($context, $reason, $previous); } - /** - * @param list $path - */ public static function incorrectValue( mixed $data, - array $path, + ?MapperContext $context, string $expectedValueDescription, ?Throwable $previous = null ): self { $describedValue = self::describeValue($data); $reason = "Expected {$expectedValueDescription}, got {$describedValue}"; - return new self($path, $reason, $previous); + return new self($context, $reason, $previous); } - /** - * @param list $path - */ public static function missingKey( - array $path, + ?MapperContext $context, string $missingKey, ?Throwable $previous = null ): self { $missingKeyDescription = self::describeValue($missingKey); $reason = "Missing required key {$missingKeyDescription}"; - return new self($path, $reason, $previous); + return new self($context, $reason, $previous); } /** - * @param list $path * @param non-empty-list $extraKeys */ public static function extraKeys( - array $path, + ?MapperContext $context, array $extraKeys, ?Throwable $previous = null ): self { $keyLabel = count($extraKeys) > 1 ? 'keys' : 'key'; $reason = "Unrecognized {$keyLabel} " . self::humanImplode(array_map(self::describeValue(...), $extraKeys)); - return new self($path, $reason, $previous); + return new self($context, $reason, $previous); } /** diff --git a/src/Runtime/Mapper.php b/src/Runtime/Mapper.php index b8eb9c1..8d5ade5 100644 --- a/src/Runtime/Mapper.php +++ b/src/Runtime/Mapper.php @@ -11,10 +11,9 @@ interface Mapper { /** - * @param list $path * @return T * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): mixed; + public function map(mixed $data, ?MapperContext $context = null): mixed; } diff --git a/src/Runtime/MapperContext.php b/src/Runtime/MapperContext.php new file mode 100644 index 0000000..6e1717b --- /dev/null +++ b/src/Runtime/MapperContext.php @@ -0,0 +1,47 @@ + $path + */ + public static function fromPath(array $path): ?self + { + $context = null; + + foreach ($path as $key) { + $context = new self($context, $key); + } + + return $context; + } + + /** + * @return list + */ + public function getPath(): array + { + return $this->parent === null + ? [$this->key] + : [...$this->parent->getPath(), $this->key]; + } + +} diff --git a/src/Runtime/Optional.php b/src/Runtime/Optional.php index 910bd72..cb4a297 100644 --- a/src/Runtime/Optional.php +++ b/src/Runtime/Optional.php @@ -10,12 +10,9 @@ abstract class Optional { - /** - * @param list $path - */ - public static function none(array $path, string $key): OptionalNone + public static function none(?MapperContext $context, string $key): OptionalNone { - return new OptionalNone($path, $key); + return new OptionalNone($context, $key); } /** diff --git a/src/Runtime/OptionalNone.php b/src/Runtime/OptionalNone.php index 192953f..6b262f7 100644 --- a/src/Runtime/OptionalNone.php +++ b/src/Runtime/OptionalNone.php @@ -11,11 +11,8 @@ final class OptionalNone extends Optional { - /** - * @param list $path - */ protected function __construct( - private readonly array $path, + private readonly ?MapperContext $context, private readonly string $key, ) { @@ -36,7 +33,7 @@ public function get(): never */ public function require(): never { - throw MappingFailedException::missingKey($this->path, $this->key); + throw MappingFailedException::missingKey($this->context, $this->key); } /** diff --git a/tests/Compiler/Mapper/Array/Data/EmptySealedArrayShapeMapper.php b/tests/Compiler/Mapper/Array/Data/EmptySealedArrayShapeMapper.php index 9d1f4c0..d682318 100644 --- a/tests/Compiler/Mapper/Array/Data/EmptySealedArrayShapeMapper.php +++ b/tests/Compiler/Mapper/Array/Data/EmptySealedArrayShapeMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Array\MapArrayShape; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function array_diff_key; use function array_keys; @@ -23,14 +24,13 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return array{} * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): array + public function map(mixed $data, ?MapperContext $context = null): array { if (!is_array($data)) { - throw MappingFailedException::incorrectType($data, $path, 'array'); + throw MappingFailedException::incorrectType($data, $context, 'array'); } $mapped = []; @@ -38,7 +38,7 @@ public function map(mixed $data, array $path = []): array $extraKeys = array_diff_key($data, $knownKeys); if (count($extraKeys) > 0) { - throw MappingFailedException::extraKeys($path, array_keys($extraKeys)); + throw MappingFailedException::extraKeys($context, array_keys($extraKeys)); } return $mapped; diff --git a/tests/Compiler/Mapper/Array/Data/EmptyUnsealedArrayShapeMapper.php b/tests/Compiler/Mapper/Array/Data/EmptyUnsealedArrayShapeMapper.php index 19e9f42..dea15e5 100644 --- a/tests/Compiler/Mapper/Array/Data/EmptyUnsealedArrayShapeMapper.php +++ b/tests/Compiler/Mapper/Array/Data/EmptyUnsealedArrayShapeMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Array\MapArrayShape; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_array; @@ -20,14 +21,13 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return array{...} * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): array + public function map(mixed $data, ?MapperContext $context = null): array { if (!is_array($data)) { - throw MappingFailedException::incorrectType($data, $path, 'array'); + throw MappingFailedException::incorrectType($data, $context, 'array'); } $mapped = []; diff --git a/tests/Compiler/Mapper/Array/Data/GenericArrayMapper.php b/tests/Compiler/Mapper/Array/Data/GenericArrayMapper.php index fec4e2f..02b5f54 100644 --- a/tests/Compiler/Mapper/Array/Data/GenericArrayMapper.php +++ b/tests/Compiler/Mapper/Array/Data/GenericArrayMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Array\MapArray; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_array; use function is_int; @@ -22,25 +23,24 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return array * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): array + public function map(mixed $data, ?MapperContext $context = null): array { if (!is_array($data)) { - throw MappingFailedException::incorrectType($data, $path, 'array'); + throw MappingFailedException::incorrectType($data, $context, 'array'); } $mapped = []; foreach ($data as $key => $value) { if (!is_string($key)) { - throw MappingFailedException::incorrectType($key, [...$path, $key], 'string'); + throw MappingFailedException::incorrectType($key, MapperContext::append($context, $key), 'string'); } if (!is_int($value)) { - throw MappingFailedException::incorrectType($value, [...$path, $key], 'int'); + throw MappingFailedException::incorrectType($value, MapperContext::append($context, $key), 'int'); } $mapped[$key] = $value; diff --git a/tests/Compiler/Mapper/Array/Data/GenericListMapper.php b/tests/Compiler/Mapper/Array/Data/GenericListMapper.php index 40c0e0c..f1c1310 100644 --- a/tests/Compiler/Mapper/Array/Data/GenericListMapper.php +++ b/tests/Compiler/Mapper/Array/Data/GenericListMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Array\MapList; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function array_is_list; use function is_array; @@ -22,21 +23,20 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return list * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): array + public function map(mixed $data, ?MapperContext $context = null): array { if (!is_array($data) || !array_is_list($data)) { - throw MappingFailedException::incorrectType($data, $path, 'list'); + throw MappingFailedException::incorrectType($data, $context, 'list'); } $mapped = []; foreach ($data as $index => $item) { if (!is_int($item)) { - throw MappingFailedException::incorrectType($item, [...$path, $index], 'int'); + throw MappingFailedException::incorrectType($item, MapperContext::append($context, $index), 'int'); } $mapped[] = $item; diff --git a/tests/Compiler/Mapper/Array/Data/SealedArrayShapeMapper.php b/tests/Compiler/Mapper/Array/Data/SealedArrayShapeMapper.php index 4538bb2..40d028b 100644 --- a/tests/Compiler/Mapper/Array/Data/SealedArrayShapeMapper.php +++ b/tests/Compiler/Mapper/Array/Data/SealedArrayShapeMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Array\MapArrayShape; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function array_diff_key; use function array_key_exists; @@ -26,59 +27,56 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return array{a: int, b?: string} * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): array + public function map(mixed $data, ?MapperContext $context = null): array { if (!is_array($data)) { - throw MappingFailedException::incorrectType($data, $path, 'array'); + throw MappingFailedException::incorrectType($data, $context, 'array'); } $mapped = []; if (!array_key_exists('a', $data)) { - throw MappingFailedException::missingKey($path, 'a'); + throw MappingFailedException::missingKey($context, 'a'); } - $mapped['a'] = $this->mapA($data['a'], [...$path, 'a']); + $mapped['a'] = $this->mapA($data['a'], MapperContext::append($context, 'a')); if (array_key_exists('b', $data)) { - $mapped['b'] = $this->mapB($data['b'], [...$path, 'b']); + $mapped['b'] = $this->mapB($data['b'], MapperContext::append($context, 'b')); } $knownKeys = ['a' => true, 'b' => true]; $extraKeys = array_diff_key($data, $knownKeys); if (count($extraKeys) > 0) { - throw MappingFailedException::extraKeys($path, array_keys($extraKeys)); + throw MappingFailedException::extraKeys($context, array_keys($extraKeys)); } return $mapped; } /** - * @param list $path * @throws MappingFailedException */ - private function mapA(mixed $data, array $path = []): int + private function mapA(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } return $data; } /** - * @param list $path * @throws MappingFailedException */ - private function mapB(mixed $data, array $path = []): string + private function mapB(mixed $data, ?MapperContext $context = null): string { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } return $data; diff --git a/tests/Compiler/Mapper/Data/MapMultiplyBySeven.php b/tests/Compiler/Mapper/Data/MapMultiplyBySeven.php index 9a16e8c..cff8e4d 100644 --- a/tests/Compiler/Mapper/Data/MapMultiplyBySeven.php +++ b/tests/Compiler/Mapper/Data/MapMultiplyBySeven.php @@ -6,15 +6,16 @@ use PHPStan\PhpDocParser\Ast\Type\TypeNode; use ShipMonk\InputMapper\Compiler\Mapper\MapRuntime; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; +use ShipMonk\InputMapper\Runtime\MapperContext; use function is_int; class MapMultiplyBySeven extends MapRuntime { - public static function mapValue(mixed $value, array $path): int + public static function mapValue(mixed $value, ?MapperContext $context): int { if (!is_int($value)) { - throw MappingFailedException::incorrectType($value, $path, 'int'); + throw MappingFailedException::incorrectType($value, $context, 'int'); } return $value * 7; diff --git a/tests/Compiler/Mapper/Data/MultiplyBySevenMapper.php b/tests/Compiler/Mapper/Data/MultiplyBySevenMapper.php index eb2c4e2..677f5e2 100644 --- a/tests/Compiler/Mapper/Data/MultiplyBySevenMapper.php +++ b/tests/Compiler/Mapper/Data/MultiplyBySevenMapper.php @@ -4,6 +4,7 @@ use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; /** @@ -18,11 +19,10 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): int + public function map(mixed $data, ?MapperContext $context = null): int { - return MapMultiplyBySeven::mapValue($data, $path); + return MapMultiplyBySeven::mapValue($data, $context); } } diff --git a/tests/Compiler/Mapper/Mixed/Data/MixedMapper.php b/tests/Compiler/Mapper/Mixed/Data/MixedMapper.php index 759bc76..225a789 100644 --- a/tests/Compiler/Mapper/Mixed/Data/MixedMapper.php +++ b/tests/Compiler/Mapper/Mixed/Data/MixedMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Mixed\MapMixed; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; /** @@ -19,10 +20,9 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): mixed + public function map(mixed $data, ?MapperContext $context = null): mixed { return $data; } diff --git a/tests/Compiler/Mapper/Object/Data/DateMapper.php b/tests/Compiler/Mapper/Object/Data/DateMapper.php index 65056d1..22186f0 100644 --- a/tests/Compiler/Mapper/Object/Data/DateMapper.php +++ b/tests/Compiler/Mapper/Object/Data/DateMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Object\MapDateTimeImmutable; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -21,19 +22,18 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $mapped = DateTimeImmutable::createFromFormat('!Y-m-d', $data); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date string in Y-m-d format'); + throw MappingFailedException::incorrectValue($data, $context, 'date string in Y-m-d format'); } return $mapped; diff --git a/tests/Compiler/Mapper/Object/Data/DateStandaloneMapper.php b/tests/Compiler/Mapper/Object/Data/DateStandaloneMapper.php index aaad686..47d3970 100644 --- a/tests/Compiler/Mapper/Object/Data/DateStandaloneMapper.php +++ b/tests/Compiler/Mapper/Object/Data/DateStandaloneMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Object\MapDate; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -21,19 +22,18 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $mapped = DateTimeImmutable::createFromFormat('!Y-m-d', $data); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date string in Y-m-d format'); + throw MappingFailedException::incorrectValue($data, $context, 'date string in Y-m-d format'); } return $mapped; diff --git a/tests/Compiler/Mapper/Object/Data/DateStandaloneWithTimeZoneMapper.php b/tests/Compiler/Mapper/Object/Data/DateStandaloneWithTimeZoneMapper.php index 393006e..aa99d0a 100644 --- a/tests/Compiler/Mapper/Object/Data/DateStandaloneWithTimeZoneMapper.php +++ b/tests/Compiler/Mapper/Object/Data/DateStandaloneWithTimeZoneMapper.php @@ -7,6 +7,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Object\MapDateTimeImmutable; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -22,20 +23,19 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $timezone = new DateTimeZone('Europe/Prague'); $mapped = DateTimeImmutable::createFromFormat('!Y-m-d', $data, $timezone); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date string in Y-m-d format'); + throw MappingFailedException::incorrectValue($data, $context, 'date string in Y-m-d format'); } return $mapped; diff --git a/tests/Compiler/Mapper/Object/Data/DateTimeImmutableMapper.php b/tests/Compiler/Mapper/Object/Data/DateTimeImmutableMapper.php index e3704a9..a2394b3 100644 --- a/tests/Compiler/Mapper/Object/Data/DateTimeImmutableMapper.php +++ b/tests/Compiler/Mapper/Object/Data/DateTimeImmutableMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Object\MapDateTimeImmutable; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -21,13 +22,12 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $mapped = DateTimeImmutable::createFromFormat('Y-m-d\\TH:i:sP', $data); @@ -37,7 +37,7 @@ public function map(mixed $data, array $path = []): DateTimeImmutable } if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date-time string in RFC 3339 format'); + throw MappingFailedException::incorrectValue($data, $context, 'date-time string in RFC 3339 format'); } return $mapped; diff --git a/tests/Compiler/Mapper/Object/Data/DateTimeImmutableWithTargetTimeZoneMapper.php b/tests/Compiler/Mapper/Object/Data/DateTimeImmutableWithTargetTimeZoneMapper.php index 06030ce..a297495 100644 --- a/tests/Compiler/Mapper/Object/Data/DateTimeImmutableWithTargetTimeZoneMapper.php +++ b/tests/Compiler/Mapper/Object/Data/DateTimeImmutableWithTargetTimeZoneMapper.php @@ -7,6 +7,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Object\MapDateTimeImmutable; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -22,13 +23,12 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $mapped = DateTimeImmutable::createFromFormat('Y-m-d\\TH:i:sP', $data); @@ -38,7 +38,7 @@ public function map(mixed $data, array $path = []): DateTimeImmutable } if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date-time string in RFC 3339 format'); + throw MappingFailedException::incorrectValue($data, $context, 'date-time string in RFC 3339 format'); } $mapped = $mapped->setTimezone(new DateTimeZone('Europe/Prague')); diff --git a/tests/Compiler/Mapper/Object/Data/DateTimeImmutableWithTimeZoneMapper.php b/tests/Compiler/Mapper/Object/Data/DateTimeImmutableWithTimeZoneMapper.php index cf1924e..0f1d8a0 100644 --- a/tests/Compiler/Mapper/Object/Data/DateTimeImmutableWithTimeZoneMapper.php +++ b/tests/Compiler/Mapper/Object/Data/DateTimeImmutableWithTimeZoneMapper.php @@ -7,6 +7,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Object\MapDateTimeImmutable; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -22,13 +23,12 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $timezone = new DateTimeZone('Europe/Prague'); @@ -39,7 +39,7 @@ public function map(mixed $data, array $path = []): DateTimeImmutable } if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date-time string in RFC 3339 format'); + throw MappingFailedException::incorrectValue($data, $context, 'date-time string in RFC 3339 format'); } $mapped = $mapped->setTimezone($timezone); diff --git a/tests/Compiler/Mapper/Object/Data/DateWithDefaultTimeZoneMapper.php b/tests/Compiler/Mapper/Object/Data/DateWithDefaultTimeZoneMapper.php index 790fa01..0cbadbb 100644 --- a/tests/Compiler/Mapper/Object/Data/DateWithDefaultTimeZoneMapper.php +++ b/tests/Compiler/Mapper/Object/Data/DateWithDefaultTimeZoneMapper.php @@ -7,6 +7,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Object\MapDateTimeImmutable; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -22,20 +23,19 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $timezone = new DateTimeZone('America/New_York'); $mapped = DateTimeImmutable::createFromFormat('!Y-m-d', $data, $timezone); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date string in Y-m-d format'); + throw MappingFailedException::incorrectValue($data, $context, 'date string in Y-m-d format'); } return $mapped; diff --git a/tests/Compiler/Mapper/Object/Data/DateWithDistinctDefaultAndTargetTimeZoneMapper.php b/tests/Compiler/Mapper/Object/Data/DateWithDistinctDefaultAndTargetTimeZoneMapper.php index bc0ded7..1b8128b 100644 --- a/tests/Compiler/Mapper/Object/Data/DateWithDistinctDefaultAndTargetTimeZoneMapper.php +++ b/tests/Compiler/Mapper/Object/Data/DateWithDistinctDefaultAndTargetTimeZoneMapper.php @@ -7,6 +7,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Object\MapDateTimeImmutable; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -22,20 +23,19 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $timezone = new DateTimeZone('Europe/Prague'); $mapped = DateTimeImmutable::createFromFormat('!Y-m-d', $data, $timezone); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date string in Y-m-d format'); + throw MappingFailedException::incorrectValue($data, $context, 'date string in Y-m-d format'); } $mapped = $mapped->setTimezone(new DateTimeZone('America/New_York')); diff --git a/tests/Compiler/Mapper/Object/Data/DateWithTargetTimeZoneMapper.php b/tests/Compiler/Mapper/Object/Data/DateWithTargetTimeZoneMapper.php index e734ce9..dd02ed3 100644 --- a/tests/Compiler/Mapper/Object/Data/DateWithTargetTimeZoneMapper.php +++ b/tests/Compiler/Mapper/Object/Data/DateWithTargetTimeZoneMapper.php @@ -7,6 +7,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Object\MapDateTimeImmutable; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -22,19 +23,18 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $mapped = DateTimeImmutable::createFromFormat('!Y-m-d', $data); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date string in Y-m-d format'); + throw MappingFailedException::incorrectValue($data, $context, 'date string in Y-m-d format'); } $mapped = $mapped->setTimezone(new DateTimeZone('America/New_York')); diff --git a/tests/Compiler/Mapper/Object/Data/DateWithTimeZoneMapper.php b/tests/Compiler/Mapper/Object/Data/DateWithTimeZoneMapper.php index aa7e0af..df77fac 100644 --- a/tests/Compiler/Mapper/Object/Data/DateWithTimeZoneMapper.php +++ b/tests/Compiler/Mapper/Object/Data/DateWithTimeZoneMapper.php @@ -7,6 +7,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Object\MapDateTimeImmutable; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -22,20 +23,19 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $timezone = new DateTimeZone('Europe/Prague'); $mapped = DateTimeImmutable::createFromFormat('!Y-m-d', $data, $timezone); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date string in Y-m-d format'); + throw MappingFailedException::incorrectValue($data, $context, 'date string in Y-m-d format'); } $mapped = $mapped->setTimezone($timezone); diff --git a/tests/Compiler/Mapper/Object/Data/MovieMapper.php b/tests/Compiler/Mapper/Object/Data/MovieMapper.php index 74b45d1..cdb7306 100644 --- a/tests/Compiler/Mapper/Object/Data/MovieMapper.php +++ b/tests/Compiler/Mapper/Object/Data/MovieMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Object\MapObject; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use ShipMonk\InputMapper\Runtime\Optional; use function array_diff_key; @@ -28,126 +29,120 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): MovieInput + public function map(mixed $data, ?MapperContext $context = null): MovieInput { if (!is_array($data)) { - throw MappingFailedException::incorrectType($data, $path, 'array'); + throw MappingFailedException::incorrectType($data, $context, 'array'); } if (!array_key_exists('id', $data)) { - throw MappingFailedException::missingKey($path, 'id'); + throw MappingFailedException::missingKey($context, 'id'); } if (!array_key_exists('title', $data)) { - throw MappingFailedException::missingKey($path, 'title'); + throw MappingFailedException::missingKey($context, 'title'); } if (!array_key_exists('year', $data)) { - throw MappingFailedException::missingKey($path, 'year'); + throw MappingFailedException::missingKey($context, 'year'); } if (!array_key_exists('genres', $data)) { - throw MappingFailedException::missingKey($path, 'genres'); + throw MappingFailedException::missingKey($context, 'genres'); } if (!array_key_exists('director', $data)) { - throw MappingFailedException::missingKey($path, 'director'); + throw MappingFailedException::missingKey($context, 'director'); } if (!array_key_exists('actors', $data)) { - throw MappingFailedException::missingKey($path, 'actors'); + throw MappingFailedException::missingKey($context, 'actors'); } $knownKeys = ['id' => true, 'title' => true, 'description' => true, 'year' => true, 'genres' => true, 'director' => true, 'actors' => true]; $extraKeys = array_diff_key($data, $knownKeys); if (count($extraKeys) > 0) { - throw MappingFailedException::extraKeys($path, array_keys($extraKeys)); + throw MappingFailedException::extraKeys($context, array_keys($extraKeys)); } return new MovieInput( - $this->mapId($data['id'], [...$path, 'id']), - $this->mapTitle($data['title'], [...$path, 'title']), - array_key_exists('description', $data) ? $this->mapDescription($data['description'], [...$path, 'description']) : Optional::none($path, 'description'), - $this->mapYear($data['year'], [...$path, 'year']), - $this->mapGenres($data['genres'], [...$path, 'genres']), - $this->mapDirector($data['director'], [...$path, 'director']), - $this->mapActors($data['actors'], [...$path, 'actors']), + $this->mapId($data['id'], MapperContext::append($context, 'id')), + $this->mapTitle($data['title'], MapperContext::append($context, 'title')), + array_key_exists('description', $data) ? $this->mapDescription($data['description'], MapperContext::append($context, 'description')) : Optional::none($context, 'description'), + $this->mapYear($data['year'], MapperContext::append($context, 'year')), + $this->mapGenres($data['genres'], MapperContext::append($context, 'genres')), + $this->mapDirector($data['director'], MapperContext::append($context, 'director')), + $this->mapActors($data['actors'], MapperContext::append($context, 'actors')), ); } /** - * @param list $path * @throws MappingFailedException */ - private function mapId(mixed $data, array $path = []): int + private function mapId(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } return $data; } /** - * @param list $path * @throws MappingFailedException */ - private function mapTitle(mixed $data, array $path = []): string + private function mapTitle(mixed $data, ?MapperContext $context = null): string { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } return $data; } /** - * @param list $path * @return Optional * @throws MappingFailedException */ - private function mapDescription(mixed $data, array $path = []): Optional + private function mapDescription(mixed $data, ?MapperContext $context = null): Optional { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } return Optional::of($data); } /** - * @param list $path * @throws MappingFailedException */ - private function mapYear(mixed $data, array $path = []): int + private function mapYear(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } return $data; } /** - * @param list $path * @return list * @throws MappingFailedException */ - private function mapGenres(mixed $data, array $path = []): array + private function mapGenres(mixed $data, ?MapperContext $context = null): array { if (!is_array($data) || !array_is_list($data)) { - throw MappingFailedException::incorrectType($data, $path, 'list'); + throw MappingFailedException::incorrectType($data, $context, 'list'); } $mapped = []; foreach ($data as $index => $item) { if (!is_string($item)) { - throw MappingFailedException::incorrectType($item, [...$path, $index], 'string'); + throw MappingFailedException::incorrectType($item, MapperContext::append($context, $index), 'string'); } $mapped[] = $item; @@ -157,29 +152,27 @@ private function mapGenres(mixed $data, array $path = []): array } /** - * @param list $path * @throws MappingFailedException */ - private function mapDirector(mixed $data, array $path = []): PersonInput + private function mapDirector(mixed $data, ?MapperContext $context = null): PersonInput { - return $this->provider->get(PersonInput::class)->map($data, $path); + return $this->provider->get(PersonInput::class)->map($data, $context); } /** - * @param list $path * @return list * @throws MappingFailedException */ - private function mapActors(mixed $data, array $path = []): array + private function mapActors(mixed $data, ?MapperContext $context = null): array { if (!is_array($data) || !array_is_list($data)) { - throw MappingFailedException::incorrectType($data, $path, 'list'); + throw MappingFailedException::incorrectType($data, $context, 'list'); } $mapped = []; foreach ($data as $index => $item) { - $mapped[] = $this->provider->get(PersonInput::class)->map($item, [...$path, $index]); + $mapped[] = $this->provider->get(PersonInput::class)->map($item, MapperContext::append($context, $index)); } return $mapped; diff --git a/tests/Compiler/Mapper/Object/Data/PersonMapper.php b/tests/Compiler/Mapper/Object/Data/PersonMapper.php index f411063..540aaa4 100644 --- a/tests/Compiler/Mapper/Object/Data/PersonMapper.php +++ b/tests/Compiler/Mapper/Object/Data/PersonMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Object\MapObject; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use ShipMonk\InputMapper\Runtime\Optional; use function array_diff_key; @@ -27,72 +28,68 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): PersonInput + public function map(mixed $data, ?MapperContext $context = null): PersonInput { if (!is_array($data)) { - throw MappingFailedException::incorrectType($data, $path, 'array'); + throw MappingFailedException::incorrectType($data, $context, 'array'); } if (!array_key_exists('id', $data)) { - throw MappingFailedException::missingKey($path, 'id'); + throw MappingFailedException::missingKey($context, 'id'); } if (!array_key_exists('name', $data)) { - throw MappingFailedException::missingKey($path, 'name'); + throw MappingFailedException::missingKey($context, 'name'); } $knownKeys = ['id' => true, 'name' => true, 'age' => true]; $extraKeys = array_diff_key($data, $knownKeys); if (count($extraKeys) > 0) { - throw MappingFailedException::extraKeys($path, array_keys($extraKeys)); + throw MappingFailedException::extraKeys($context, array_keys($extraKeys)); } return new PersonInput( - $this->mapId($data['id'], [...$path, 'id']), - $this->mapName($data['name'], [...$path, 'name']), - array_key_exists('age', $data) ? $this->mapAge($data['age'], [...$path, 'age']) : Optional::none($path, 'age'), + $this->mapId($data['id'], MapperContext::append($context, 'id')), + $this->mapName($data['name'], MapperContext::append($context, 'name')), + array_key_exists('age', $data) ? $this->mapAge($data['age'], MapperContext::append($context, 'age')) : Optional::none($context, 'age'), ); } /** - * @param list $path * @throws MappingFailedException */ - private function mapId(mixed $data, array $path = []): int + private function mapId(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } return $data; } /** - * @param list $path * @throws MappingFailedException */ - private function mapName(mixed $data, array $path = []): string + private function mapName(mixed $data, ?MapperContext $context = null): string { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } return $data; } /** - * @param list $path * @return Optional * @throws MappingFailedException */ - private function mapAge(mixed $data, array $path = []): Optional + private function mapAge(mixed $data, ?MapperContext $context = null): Optional { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } return Optional::of($data); diff --git a/tests/Compiler/Mapper/Object/Data/PersonWithAllowedExtraPropertiesMapper.php b/tests/Compiler/Mapper/Object/Data/PersonWithAllowedExtraPropertiesMapper.php index 17cf0f1..a5a944e 100644 --- a/tests/Compiler/Mapper/Object/Data/PersonWithAllowedExtraPropertiesMapper.php +++ b/tests/Compiler/Mapper/Object/Data/PersonWithAllowedExtraPropertiesMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Object\MapObject; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use ShipMonk\InputMapper\Runtime\Optional; use function array_key_exists; @@ -24,65 +25,61 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): PersonInput + public function map(mixed $data, ?MapperContext $context = null): PersonInput { if (!is_array($data)) { - throw MappingFailedException::incorrectType($data, $path, 'array'); + throw MappingFailedException::incorrectType($data, $context, 'array'); } if (!array_key_exists('id', $data)) { - throw MappingFailedException::missingKey($path, 'id'); + throw MappingFailedException::missingKey($context, 'id'); } if (!array_key_exists('name', $data)) { - throw MappingFailedException::missingKey($path, 'name'); + throw MappingFailedException::missingKey($context, 'name'); } return new PersonInput( - $this->mapId($data['id'], [...$path, 'id']), - $this->mapName($data['name'], [...$path, 'name']), - array_key_exists('age', $data) ? $this->mapAge($data['age'], [...$path, 'age']) : Optional::none($path, 'age'), + $this->mapId($data['id'], MapperContext::append($context, 'id')), + $this->mapName($data['name'], MapperContext::append($context, 'name')), + array_key_exists('age', $data) ? $this->mapAge($data['age'], MapperContext::append($context, 'age')) : Optional::none($context, 'age'), ); } /** - * @param list $path * @throws MappingFailedException */ - private function mapId(mixed $data, array $path = []): int + private function mapId(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } return $data; } /** - * @param list $path * @throws MappingFailedException */ - private function mapName(mixed $data, array $path = []): string + private function mapName(mixed $data, ?MapperContext $context = null): string { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } return $data; } /** - * @param list $path * @return Optional * @throws MappingFailedException */ - private function mapAge(mixed $data, array $path = []): Optional + private function mapAge(mixed $data, ?MapperContext $context = null): Optional { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } return Optional::of($data); diff --git a/tests/Compiler/Mapper/Object/Data/SuitEnumMapper.php b/tests/Compiler/Mapper/Object/Data/SuitEnumMapper.php index 815d57d..d8db510 100644 --- a/tests/Compiler/Mapper/Object/Data/SuitEnumMapper.php +++ b/tests/Compiler/Mapper/Object/Data/SuitEnumMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Object\MapEnum; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function array_column; use function implode; @@ -22,19 +23,18 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): SuitEnum + public function map(mixed $data, ?MapperContext $context = null): SuitEnum { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $enum = SuitEnum::tryFrom($data); if ($enum === null) { - throw MappingFailedException::incorrectValue($data, $path, 'one of ' . implode(', ', array_column(SuitEnum::cases(), 'value'))); + throw MappingFailedException::incorrectValue($data, $context, 'one of ' . implode(', ', array_column(SuitEnum::cases(), 'value'))); } return $enum; diff --git a/tests/Compiler/Mapper/Object/MapObjectTest.php b/tests/Compiler/Mapper/Object/MapObjectTest.php index d029cad..48ee1d6 100644 --- a/tests/Compiler/Mapper/Object/MapObjectTest.php +++ b/tests/Compiler/Mapper/Object/MapObjectTest.php @@ -10,6 +10,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Scalar\MapString; use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\MapOptional; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\Optional; use ShipMonkTests\InputMapper\Compiler\Mapper\MapperCompilerTestCase; use ShipMonkTests\InputMapper\Compiler\Mapper\Object\Data\MovieInput; @@ -29,10 +30,10 @@ public function testCompile(): void description: Optional::of('A computer hacker learns from mysterious rebels about the true nature of his reality and his role in the war against its controllers.'), year: 1_999, genres: ['Action', 'Sci-Fi'], - director: new PersonInput(7, 'Lana Wachowski', Optional::none(['director'], 'age')), + director: new PersonInput(7, 'Lana Wachowski', Optional::none(MapperContext::fromPath(['director']), 'age')), actors: [ new PersonInput(8, 'Keanu Reeves', age: Optional::of(56)), - new PersonInput(9, 'Laurence Fishburne', Optional::none(['actors', 1], 'age')), + new PersonInput(9, 'Laurence Fishburne', Optional::none(MapperContext::fromPath(['actors', 1]), 'age')), ], ); @@ -101,7 +102,7 @@ public function testCompileWithAllowExtraProperties(): void $mapper = $this->compileMapper('PersonWithAllowedExtraProperties', $mapperCompiler); self::assertEquals( - new PersonInput(1, 'John', Optional::none([], 'age')), + new PersonInput(1, 'John', Optional::none(null, 'age')), $mapper->map(['id' => 1, 'name' => 'John', 'extra' => 'X']), ); } diff --git a/tests/Compiler/Mapper/Scalar/Data/BoolMapper.php b/tests/Compiler/Mapper/Scalar/Data/BoolMapper.php index 23c60ed..f3f61ea 100644 --- a/tests/Compiler/Mapper/Scalar/Data/BoolMapper.php +++ b/tests/Compiler/Mapper/Scalar/Data/BoolMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Scalar\MapBool; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_bool; @@ -20,13 +21,12 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): bool + public function map(mixed $data, ?MapperContext $context = null): bool { if (!is_bool($data)) { - throw MappingFailedException::incorrectType($data, $path, 'bool'); + throw MappingFailedException::incorrectType($data, $context, 'bool'); } return $data; diff --git a/tests/Compiler/Mapper/Scalar/Data/FloatMapper.php b/tests/Compiler/Mapper/Scalar/Data/FloatMapper.php index 3f1c574..3f80567 100644 --- a/tests/Compiler/Mapper/Scalar/Data/FloatMapper.php +++ b/tests/Compiler/Mapper/Scalar/Data/FloatMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Scalar\MapFloat; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function floatval; use function is_finite; @@ -27,25 +28,24 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): float + public function map(mixed $data, ?MapperContext $context = null): float { if (is_float($data)) { if (!is_finite($data)) { - throw MappingFailedException::incorrectType($data, $path, 'finite float'); + throw MappingFailedException::incorrectType($data, $context, 'finite float'); } $mapped = $data; } elseif (is_int($data)) { if ($data < self::MIN_SAFE_INTEGER || $data > self::MAX_SAFE_INTEGER) { - throw MappingFailedException::incorrectValue($data, $path, 'float or int with value that can be losslessly converted to float'); + throw MappingFailedException::incorrectValue($data, $context, 'float or int with value that can be losslessly converted to float'); } $mapped = floatval($data); } else { - throw MappingFailedException::incorrectType($data, $path, 'float'); + throw MappingFailedException::incorrectType($data, $context, 'float'); } return $mapped; diff --git a/tests/Compiler/Mapper/Scalar/Data/FloatWithAllowedInfinityAndNanMapper.php b/tests/Compiler/Mapper/Scalar/Data/FloatWithAllowedInfinityAndNanMapper.php index de62f17..ed86a47 100644 --- a/tests/Compiler/Mapper/Scalar/Data/FloatWithAllowedInfinityAndNanMapper.php +++ b/tests/Compiler/Mapper/Scalar/Data/FloatWithAllowedInfinityAndNanMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Scalar\MapFloat; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function floatval; use function is_float; @@ -26,21 +27,20 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): float + public function map(mixed $data, ?MapperContext $context = null): float { if (is_float($data)) { $mapped = $data; } elseif (is_int($data)) { if ($data < self::MIN_SAFE_INTEGER || $data > self::MAX_SAFE_INTEGER) { - throw MappingFailedException::incorrectValue($data, $path, 'float or int with value that can be losslessly converted to float'); + throw MappingFailedException::incorrectValue($data, $context, 'float or int with value that can be losslessly converted to float'); } $mapped = floatval($data); } else { - throw MappingFailedException::incorrectType($data, $path, 'float'); + throw MappingFailedException::incorrectType($data, $context, 'float'); } return $mapped; diff --git a/tests/Compiler/Mapper/Scalar/Data/FloatWithAllowedInfinityMapper.php b/tests/Compiler/Mapper/Scalar/Data/FloatWithAllowedInfinityMapper.php index df02858..b4c3843 100644 --- a/tests/Compiler/Mapper/Scalar/Data/FloatWithAllowedInfinityMapper.php +++ b/tests/Compiler/Mapper/Scalar/Data/FloatWithAllowedInfinityMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Scalar\MapFloat; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function floatval; use function is_float; @@ -27,25 +28,24 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): float + public function map(mixed $data, ?MapperContext $context = null): float { if (is_float($data)) { if (is_nan($data)) { - throw MappingFailedException::incorrectType($data, $path, 'finite float or INF'); + throw MappingFailedException::incorrectType($data, $context, 'finite float or INF'); } $mapped = $data; } elseif (is_int($data)) { if ($data < self::MIN_SAFE_INTEGER || $data > self::MAX_SAFE_INTEGER) { - throw MappingFailedException::incorrectValue($data, $path, 'float or int with value that can be losslessly converted to float'); + throw MappingFailedException::incorrectValue($data, $context, 'float or int with value that can be losslessly converted to float'); } $mapped = floatval($data); } else { - throw MappingFailedException::incorrectType($data, $path, 'float'); + throw MappingFailedException::incorrectType($data, $context, 'float'); } return $mapped; diff --git a/tests/Compiler/Mapper/Scalar/Data/FloatWithAllowedNanMapper.php b/tests/Compiler/Mapper/Scalar/Data/FloatWithAllowedNanMapper.php index 42e5a09..b353b07 100644 --- a/tests/Compiler/Mapper/Scalar/Data/FloatWithAllowedNanMapper.php +++ b/tests/Compiler/Mapper/Scalar/Data/FloatWithAllowedNanMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Scalar\MapFloat; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function floatval; use function is_float; @@ -27,25 +28,24 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): float + public function map(mixed $data, ?MapperContext $context = null): float { if (is_float($data)) { if (is_infinite($data)) { - throw MappingFailedException::incorrectType($data, $path, 'finite float or NAN'); + throw MappingFailedException::incorrectType($data, $context, 'finite float or NAN'); } $mapped = $data; } elseif (is_int($data)) { if ($data < self::MIN_SAFE_INTEGER || $data > self::MAX_SAFE_INTEGER) { - throw MappingFailedException::incorrectValue($data, $path, 'float or int with value that can be losslessly converted to float'); + throw MappingFailedException::incorrectValue($data, $context, 'float or int with value that can be losslessly converted to float'); } $mapped = floatval($data); } else { - throw MappingFailedException::incorrectType($data, $path, 'float'); + throw MappingFailedException::incorrectType($data, $context, 'float'); } return $mapped; diff --git a/tests/Compiler/Mapper/Scalar/Data/IntMapper.php b/tests/Compiler/Mapper/Scalar/Data/IntMapper.php index c0c8c3d..80d7ecf 100644 --- a/tests/Compiler/Mapper/Scalar/Data/IntMapper.php +++ b/tests/Compiler/Mapper/Scalar/Data/IntMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Scalar\MapInt; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_int; @@ -20,13 +21,12 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): int + public function map(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } return $data; diff --git a/tests/Compiler/Mapper/Scalar/Data/StringMapper.php b/tests/Compiler/Mapper/Scalar/Data/StringMapper.php index 3e57571..c248bed 100644 --- a/tests/Compiler/Mapper/Scalar/Data/StringMapper.php +++ b/tests/Compiler/Mapper/Scalar/Data/StringMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Scalar\MapString; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -20,13 +21,12 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): string + public function map(mixed $data, ?MapperContext $context = null): string { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } return $data; diff --git a/tests/Compiler/Mapper/Wrapper/Data/DoubleIntMapper.php b/tests/Compiler/Mapper/Wrapper/Data/DoubleIntMapper.php index fd96607..90d1a10 100644 --- a/tests/Compiler/Mapper/Wrapper/Data/DoubleIntMapper.php +++ b/tests/Compiler/Mapper/Wrapper/Data/DoubleIntMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ChainMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_int; @@ -20,15 +21,14 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): int + public function map(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } - return MapToDouble::mapValue($data, $path); + return MapToDouble::mapValue($data, $context); } } diff --git a/tests/Compiler/Mapper/Wrapper/Data/MapToDouble.php b/tests/Compiler/Mapper/Wrapper/Data/MapToDouble.php index b6e61ef..95ef398 100644 --- a/tests/Compiler/Mapper/Wrapper/Data/MapToDouble.php +++ b/tests/Compiler/Mapper/Wrapper/Data/MapToDouble.php @@ -5,13 +5,14 @@ use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; use PHPStan\PhpDocParser\Ast\Type\TypeNode; use ShipMonk\InputMapper\Compiler\Mapper\MapRuntime; +use ShipMonk\InputMapper\Runtime\MapperContext; use function assert; use function is_int; class MapToDouble extends MapRuntime { - public static function mapValue(mixed $value, array $path): int + public static function mapValue(mixed $value, ?MapperContext $context): int { assert(is_int($value)); return $value * 2; diff --git a/tests/Compiler/Mapper/Wrapper/Data/NotValidatedIntMapperMapper.php b/tests/Compiler/Mapper/Wrapper/Data/NotValidatedIntMapperMapper.php index 98b8e7a..bf2edf4 100644 --- a/tests/Compiler/Mapper/Wrapper/Data/NotValidatedIntMapperMapper.php +++ b/tests/Compiler/Mapper/Wrapper/Data/NotValidatedIntMapperMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_int; @@ -20,13 +21,12 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): int + public function map(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } return $data; diff --git a/tests/Compiler/Mapper/Wrapper/Data/NullableIntMapper.php b/tests/Compiler/Mapper/Wrapper/Data/NullableIntMapper.php index 291de8d..6abad1d 100644 --- a/tests/Compiler/Mapper/Wrapper/Data/NullableIntMapper.php +++ b/tests/Compiler/Mapper/Wrapper/Data/NullableIntMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\MapNullable; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_int; @@ -20,16 +21,15 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): ?int + public function map(mixed $data, ?MapperContext $context = null): ?int { if ($data === null) { $mapped = null; } else { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } $mapped = $data; diff --git a/tests/Compiler/Mapper/Wrapper/Data/NullableMixedMapper.php b/tests/Compiler/Mapper/Wrapper/Data/NullableMixedMapper.php index 53721bc..f4d3420 100644 --- a/tests/Compiler/Mapper/Wrapper/Data/NullableMixedMapper.php +++ b/tests/Compiler/Mapper/Wrapper/Data/NullableMixedMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\MapNullable; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; /** @@ -19,10 +20,9 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): mixed + public function map(mixed $data, ?MapperContext $context = null): mixed { if ($data === null) { $mapped = null; diff --git a/tests/Compiler/Mapper/Wrapper/Data/OptionalIntMapper.php b/tests/Compiler/Mapper/Wrapper/Data/OptionalIntMapper.php index cbd7740..3720126 100644 --- a/tests/Compiler/Mapper/Wrapper/Data/OptionalIntMapper.php +++ b/tests/Compiler/Mapper/Wrapper/Data/OptionalIntMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\MapOptional; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use ShipMonk\InputMapper\Runtime\Optional; use function is_int; @@ -21,14 +22,13 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return Optional * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): Optional + public function map(mixed $data, ?MapperContext $context = null): Optional { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } return Optional::of($data); diff --git a/tests/Compiler/Mapper/Wrapper/Data/PositiveIntMapperMapper.php b/tests/Compiler/Mapper/Wrapper/Data/PositiveIntMapperMapper.php index fbb1110..7ff9a1c 100644 --- a/tests/Compiler/Mapper/Wrapper/Data/PositiveIntMapperMapper.php +++ b/tests/Compiler/Mapper/Wrapper/Data/PositiveIntMapperMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_int; @@ -20,18 +21,17 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return positive-int * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): int + public function map(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } if ($data <= 0) { - throw MappingFailedException::incorrectValue($data, $path, 'value greater than 0'); + throw MappingFailedException::incorrectValue($data, $context, 'value greater than 0'); } return $data; diff --git a/tests/Compiler/Validator/Array/Data/ListItemValidatorCalledWithCorrectItemTypeMapper.php b/tests/Compiler/Validator/Array/Data/ListItemValidatorCalledWithCorrectItemTypeMapper.php index 426e373..d66d542 100644 --- a/tests/Compiler/Validator/Array/Data/ListItemValidatorCalledWithCorrectItemTypeMapper.php +++ b/tests/Compiler/Validator/Array/Data/ListItemValidatorCalledWithCorrectItemTypeMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function array_is_list; use function is_array; @@ -22,21 +23,20 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return list * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): array + public function map(mixed $data, ?MapperContext $context = null): array { if (!is_array($data) || !array_is_list($data)) { - throw MappingFailedException::incorrectType($data, $path, 'list'); + throw MappingFailedException::incorrectType($data, $context, 'list'); } $mapped = []; foreach ($data as $index => $item) { if (!is_int($item)) { - throw MappingFailedException::incorrectType($item, [...$path, $index], 'int'); + throw MappingFailedException::incorrectType($item, MapperContext::append($context, $index), 'int'); } $mapped[] = $item; diff --git a/tests/Compiler/Validator/Array/Data/ListItemValidatorMapper.php b/tests/Compiler/Validator/Array/Data/ListItemValidatorMapper.php index e651381..f8af808 100644 --- a/tests/Compiler/Validator/Array/Data/ListItemValidatorMapper.php +++ b/tests/Compiler/Validator/Array/Data/ListItemValidatorMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function array_is_list; use function is_array; @@ -22,21 +23,20 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return list * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): array + public function map(mixed $data, ?MapperContext $context = null): array { if (!is_array($data) || !array_is_list($data)) { - throw MappingFailedException::incorrectType($data, $path, 'list'); + throw MappingFailedException::incorrectType($data, $context, 'list'); } $mapped = []; foreach ($data as $index => $item) { if (!is_int($item)) { - throw MappingFailedException::incorrectType($item, [...$path, $index], 'int'); + throw MappingFailedException::incorrectType($item, MapperContext::append($context, $index), 'int'); } $mapped[] = $item; @@ -44,7 +44,7 @@ public function map(mixed $data, array $path = []): array foreach ($mapped as $index2 => $item2) { if ($item2 <= 0) { - throw MappingFailedException::incorrectValue($item2, [...$path, $index2], 'value greater than 0'); + throw MappingFailedException::incorrectValue($item2, MapperContext::append($context, $index2), 'value greater than 0'); } } diff --git a/tests/Compiler/Validator/Array/Data/ListItemValidatorWithMultipleValidatorsMapper.php b/tests/Compiler/Validator/Array/Data/ListItemValidatorWithMultipleValidatorsMapper.php index 2cf1531..b6a2a7f 100644 --- a/tests/Compiler/Validator/Array/Data/ListItemValidatorWithMultipleValidatorsMapper.php +++ b/tests/Compiler/Validator/Array/Data/ListItemValidatorWithMultipleValidatorsMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function array_is_list; use function is_array; @@ -22,21 +23,20 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return list * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): array + public function map(mixed $data, ?MapperContext $context = null): array { if (!is_array($data) || !array_is_list($data)) { - throw MappingFailedException::incorrectType($data, $path, 'list'); + throw MappingFailedException::incorrectType($data, $context, 'list'); } $mapped = []; foreach ($data as $index => $item) { if (!is_int($item)) { - throw MappingFailedException::incorrectType($item, [...$path, $index], 'int'); + throw MappingFailedException::incorrectType($item, MapperContext::append($context, $index), 'int'); } $mapped[] = $item; @@ -44,11 +44,11 @@ public function map(mixed $data, array $path = []): array foreach ($mapped as $index2 => $item2) { if ($item2 <= 0) { - throw MappingFailedException::incorrectValue($item2, [...$path, $index2], 'value greater than 0'); + throw MappingFailedException::incorrectValue($item2, MapperContext::append($context, $index2), 'value greater than 0'); } if ($item2 % 5 !== 0) { - throw MappingFailedException::incorrectValue($item2, [...$path, $index2], 'multiple of 5'); + throw MappingFailedException::incorrectValue($item2, MapperContext::append($context, $index2), 'multiple of 5'); } } diff --git a/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithExactMapper.php b/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithExactMapper.php index 43224b5..2ed7bb3 100644 --- a/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithExactMapper.php +++ b/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithExactMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function array_is_list; use function count; @@ -22,14 +23,13 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return non-empty-list * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): array + public function map(mixed $data, ?MapperContext $context = null): array { if (!is_array($data) || !array_is_list($data)) { - throw MappingFailedException::incorrectType($data, $path, 'list'); + throw MappingFailedException::incorrectType($data, $context, 'list'); } $mapped = []; @@ -39,7 +39,7 @@ public function map(mixed $data, array $path = []): array } if (count($mapped) !== 5) { - throw MappingFailedException::incorrectValue($mapped, $path, 'list with exactly 5 items'); + throw MappingFailedException::incorrectValue($mapped, $context, 'list with exactly 5 items'); } return $mapped; diff --git a/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithMaxMapper.php b/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithMaxMapper.php index 50317b8..ad52aec 100644 --- a/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithMaxMapper.php +++ b/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithMaxMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function array_is_list; use function count; @@ -22,14 +23,13 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return list * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): array + public function map(mixed $data, ?MapperContext $context = null): array { if (!is_array($data) || !array_is_list($data)) { - throw MappingFailedException::incorrectType($data, $path, 'list'); + throw MappingFailedException::incorrectType($data, $context, 'list'); } $mapped = []; @@ -39,7 +39,7 @@ public function map(mixed $data, array $path = []): array } if (count($mapped) > 5) { - throw MappingFailedException::incorrectValue($mapped, $path, 'list with at most 5 items'); + throw MappingFailedException::incorrectValue($mapped, $context, 'list with at most 5 items'); } return $mapped; diff --git a/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithMinAndMaxMapper.php b/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithMinAndMaxMapper.php index eb633d3..b852ea1 100644 --- a/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithMinAndMaxMapper.php +++ b/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithMinAndMaxMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function array_is_list; use function count; @@ -22,14 +23,13 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return non-empty-list * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): array + public function map(mixed $data, ?MapperContext $context = null): array { if (!is_array($data) || !array_is_list($data)) { - throw MappingFailedException::incorrectType($data, $path, 'list'); + throw MappingFailedException::incorrectType($data, $context, 'list'); } $mapped = []; @@ -39,11 +39,11 @@ public function map(mixed $data, array $path = []): array } if (count($mapped) < 1) { - throw MappingFailedException::incorrectValue($mapped, $path, 'list with at least 1 items'); + throw MappingFailedException::incorrectValue($mapped, $context, 'list with at least 1 items'); } if (count($mapped) > 5) { - throw MappingFailedException::incorrectValue($mapped, $path, 'list with at most 5 items'); + throw MappingFailedException::incorrectValue($mapped, $context, 'list with at most 5 items'); } return $mapped; diff --git a/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithMinMapper.php b/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithMinMapper.php index 52b2a72..310c4e4 100644 --- a/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithMinMapper.php +++ b/tests/Compiler/Validator/Array/Data/ListLengthValidatorWithMinMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function array_is_list; use function count; @@ -23,28 +24,27 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return non-empty-list * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): array + public function map(mixed $data, ?MapperContext $context = null): array { if (!is_array($data) || !array_is_list($data)) { - throw MappingFailedException::incorrectType($data, $path, 'list'); + throw MappingFailedException::incorrectType($data, $context, 'list'); } $mapped = []; foreach ($data as $index => $item) { if (!is_string($item)) { - throw MappingFailedException::incorrectType($item, [...$path, $index], 'string'); + throw MappingFailedException::incorrectType($item, MapperContext::append($context, $index), 'string'); } $mapped[] = $item; } if (count($mapped) < 2) { - throw MappingFailedException::incorrectValue($mapped, $path, 'list with at least 2 items'); + throw MappingFailedException::incorrectValue($mapped, $context, 'list with at least 2 items'); } return $mapped; diff --git a/tests/Compiler/Validator/Array/Data/NoopListLengthValidatorMapper.php b/tests/Compiler/Validator/Array/Data/NoopListLengthValidatorMapper.php index 4846927..607274b 100644 --- a/tests/Compiler/Validator/Array/Data/NoopListLengthValidatorMapper.php +++ b/tests/Compiler/Validator/Array/Data/NoopListLengthValidatorMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function array_is_list; use function count; @@ -22,14 +23,13 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return list * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): array + public function map(mixed $data, ?MapperContext $context = null): array { if (!is_array($data) || !array_is_list($data)) { - throw MappingFailedException::incorrectType($data, $path, 'list'); + throw MappingFailedException::incorrectType($data, $context, 'list'); } $mapped = []; diff --git a/tests/Compiler/Validator/Data/AssertMultipleOfSeven.php b/tests/Compiler/Validator/Data/AssertMultipleOfSeven.php index 19c01fe..ee19287 100644 --- a/tests/Compiler/Validator/Data/AssertMultipleOfSeven.php +++ b/tests/Compiler/Validator/Data/AssertMultipleOfSeven.php @@ -4,19 +4,19 @@ use ShipMonk\InputMapper\Compiler\Validator\AssertRuntime; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; +use ShipMonk\InputMapper\Runtime\MapperContext; use function is_int; class AssertMultipleOfSeven extends AssertRuntime { /** - * @param list $path * @throws MappingFailedException */ - public static function assertValue(mixed $value, array $path): void + public static function assertValue(mixed $value, ?MapperContext $context = null): void { if (is_int($value) && $value % 7 !== 0) { - throw MappingFailedException::incorrectValue($value, $path, 'multiple of 7'); + throw MappingFailedException::incorrectValue($value, $context, 'multiple of 7'); } } diff --git a/tests/Compiler/Validator/Data/MultipleOfSevenValidatorMapper.php b/tests/Compiler/Validator/Data/MultipleOfSevenValidatorMapper.php index 16f0aa3..da06d94 100644 --- a/tests/Compiler/Validator/Data/MultipleOfSevenValidatorMapper.php +++ b/tests/Compiler/Validator/Data/MultipleOfSevenValidatorMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; /** @@ -19,12 +20,11 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): mixed + public function map(mixed $data, ?MapperContext $context = null): mixed { - AssertMultipleOfSeven::assertValue($data, $path); + AssertMultipleOfSeven::assertValue($data, $context); return $data; } } diff --git a/tests/Compiler/Validator/Float/Data/FloatMultipleOfFiveMapper.php b/tests/Compiler/Validator/Float/Data/FloatMultipleOfFiveMapper.php index 2c93f1b..8f7732e 100644 --- a/tests/Compiler/Validator/Float/Data/FloatMultipleOfFiveMapper.php +++ b/tests/Compiler/Validator/Float/Data/FloatMultipleOfFiveMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function floatval; use function is_finite; @@ -28,29 +29,28 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): float + public function map(mixed $data, ?MapperContext $context = null): float { if (is_float($data)) { if (!is_finite($data)) { - throw MappingFailedException::incorrectType($data, $path, 'finite float'); + throw MappingFailedException::incorrectType($data, $context, 'finite float'); } $mapped = $data; } elseif (is_int($data)) { if ($data < self::MIN_SAFE_INTEGER || $data > self::MAX_SAFE_INTEGER) { - throw MappingFailedException::incorrectValue($data, $path, 'float or int with value that can be losslessly converted to float'); + throw MappingFailedException::incorrectValue($data, $context, 'float or int with value that can be losslessly converted to float'); } $mapped = floatval($data); } else { - throw MappingFailedException::incorrectType($data, $path, 'float'); + throw MappingFailedException::incorrectType($data, $context, 'float'); } if (!Floats::isInteger($mapped / 5.0)) { - throw MappingFailedException::incorrectValue($mapped, $path, 'multiple of 5'); + throw MappingFailedException::incorrectValue($mapped, $context, 'multiple of 5'); } return $mapped; diff --git a/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithExclusiveLowerBoundMapper.php b/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithExclusiveLowerBoundMapper.php index 273b5b3..3ba17c7 100644 --- a/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithExclusiveLowerBoundMapper.php +++ b/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithExclusiveLowerBoundMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function floatval; use function is_finite; @@ -28,29 +29,28 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): float + public function map(mixed $data, ?MapperContext $context = null): float { if (is_float($data)) { if (!is_finite($data)) { - throw MappingFailedException::incorrectType($data, $path, 'finite float'); + throw MappingFailedException::incorrectType($data, $context, 'finite float'); } $mapped = $data; } elseif (is_int($data)) { if ($data < self::MIN_SAFE_INTEGER || $data > self::MAX_SAFE_INTEGER) { - throw MappingFailedException::incorrectValue($data, $path, 'float or int with value that can be losslessly converted to float'); + throw MappingFailedException::incorrectValue($data, $context, 'float or int with value that can be losslessly converted to float'); } $mapped = floatval($data); } else { - throw MappingFailedException::incorrectType($data, $path, 'float'); + throw MappingFailedException::incorrectType($data, $context, 'float'); } if (Floats::isLessThanOrEqualTo($mapped, 5.0)) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value greater than 5'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value greater than 5'); } return $mapped; diff --git a/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithExclusiveUpperBoundMapper.php b/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithExclusiveUpperBoundMapper.php index 1dad6ae..5dad0e1 100644 --- a/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithExclusiveUpperBoundMapper.php +++ b/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithExclusiveUpperBoundMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function floatval; use function is_finite; @@ -28,29 +29,28 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): float + public function map(mixed $data, ?MapperContext $context = null): float { if (is_float($data)) { if (!is_finite($data)) { - throw MappingFailedException::incorrectType($data, $path, 'finite float'); + throw MappingFailedException::incorrectType($data, $context, 'finite float'); } $mapped = $data; } elseif (is_int($data)) { if ($data < self::MIN_SAFE_INTEGER || $data > self::MAX_SAFE_INTEGER) { - throw MappingFailedException::incorrectValue($data, $path, 'float or int with value that can be losslessly converted to float'); + throw MappingFailedException::incorrectValue($data, $context, 'float or int with value that can be losslessly converted to float'); } $mapped = floatval($data); } else { - throw MappingFailedException::incorrectType($data, $path, 'float'); + throw MappingFailedException::incorrectType($data, $context, 'float'); } if (Floats::isGreaterThanOrEqualTo($mapped, 5.0)) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value less than 5'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value less than 5'); } return $mapped; diff --git a/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithInclusiveLowerAndUpperBoundMapper.php b/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithInclusiveLowerAndUpperBoundMapper.php index b287e05..a8be072 100644 --- a/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithInclusiveLowerAndUpperBoundMapper.php +++ b/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithInclusiveLowerAndUpperBoundMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function floatval; use function is_finite; @@ -28,33 +29,32 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): float + public function map(mixed $data, ?MapperContext $context = null): float { if (is_float($data)) { if (!is_finite($data)) { - throw MappingFailedException::incorrectType($data, $path, 'finite float'); + throw MappingFailedException::incorrectType($data, $context, 'finite float'); } $mapped = $data; } elseif (is_int($data)) { if ($data < self::MIN_SAFE_INTEGER || $data > self::MAX_SAFE_INTEGER) { - throw MappingFailedException::incorrectValue($data, $path, 'float or int with value that can be losslessly converted to float'); + throw MappingFailedException::incorrectValue($data, $context, 'float or int with value that can be losslessly converted to float'); } $mapped = floatval($data); } else { - throw MappingFailedException::incorrectType($data, $path, 'float'); + throw MappingFailedException::incorrectType($data, $context, 'float'); } if (Floats::isLessThan($mapped, 5.0)) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value greater than or equal to 5'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value greater than or equal to 5'); } if (Floats::isGreaterThan($mapped, 10.0)) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value less than or equal to 10'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value less than or equal to 10'); } return $mapped; diff --git a/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithInclusiveLowerBoundMapper.php b/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithInclusiveLowerBoundMapper.php index bed8845..feeec84 100644 --- a/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithInclusiveLowerBoundMapper.php +++ b/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithInclusiveLowerBoundMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function floatval; use function is_finite; @@ -28,29 +29,28 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): float + public function map(mixed $data, ?MapperContext $context = null): float { if (is_float($data)) { if (!is_finite($data)) { - throw MappingFailedException::incorrectType($data, $path, 'finite float'); + throw MappingFailedException::incorrectType($data, $context, 'finite float'); } $mapped = $data; } elseif (is_int($data)) { if ($data < self::MIN_SAFE_INTEGER || $data > self::MAX_SAFE_INTEGER) { - throw MappingFailedException::incorrectValue($data, $path, 'float or int with value that can be losslessly converted to float'); + throw MappingFailedException::incorrectValue($data, $context, 'float or int with value that can be losslessly converted to float'); } $mapped = floatval($data); } else { - throw MappingFailedException::incorrectType($data, $path, 'float'); + throw MappingFailedException::incorrectType($data, $context, 'float'); } if (Floats::isLessThan($mapped, 5.0)) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value greater than or equal to 5'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value greater than or equal to 5'); } return $mapped; diff --git a/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithInclusiveUpperBoundMapper.php b/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithInclusiveUpperBoundMapper.php index 01cc352..facec02 100644 --- a/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithInclusiveUpperBoundMapper.php +++ b/tests/Compiler/Validator/Float/Data/FloatRangeValidatorWithInclusiveUpperBoundMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function floatval; use function is_finite; @@ -28,29 +29,28 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): float + public function map(mixed $data, ?MapperContext $context = null): float { if (is_float($data)) { if (!is_finite($data)) { - throw MappingFailedException::incorrectType($data, $path, 'finite float'); + throw MappingFailedException::incorrectType($data, $context, 'finite float'); } $mapped = $data; } elseif (is_int($data)) { if ($data < self::MIN_SAFE_INTEGER || $data > self::MAX_SAFE_INTEGER) { - throw MappingFailedException::incorrectValue($data, $path, 'float or int with value that can be losslessly converted to float'); + throw MappingFailedException::incorrectValue($data, $context, 'float or int with value that can be losslessly converted to float'); } $mapped = floatval($data); } else { - throw MappingFailedException::incorrectType($data, $path, 'float'); + throw MappingFailedException::incorrectType($data, $context, 'float'); } if (Floats::isGreaterThan($mapped, 5.0)) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value less than or equal to 5'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value less than or equal to 5'); } return $mapped; diff --git a/tests/Compiler/Validator/Float/Data/FloatWithAtMostTwoDecimalPlacesMapper.php b/tests/Compiler/Validator/Float/Data/FloatWithAtMostTwoDecimalPlacesMapper.php index bfbf2eb..7975738 100644 --- a/tests/Compiler/Validator/Float/Data/FloatWithAtMostTwoDecimalPlacesMapper.php +++ b/tests/Compiler/Validator/Float/Data/FloatWithAtMostTwoDecimalPlacesMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function floatval; use function is_finite; @@ -28,29 +29,28 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): float + public function map(mixed $data, ?MapperContext $context = null): float { if (is_float($data)) { if (!is_finite($data)) { - throw MappingFailedException::incorrectType($data, $path, 'finite float'); + throw MappingFailedException::incorrectType($data, $context, 'finite float'); } $mapped = $data; } elseif (is_int($data)) { if ($data < self::MIN_SAFE_INTEGER || $data > self::MAX_SAFE_INTEGER) { - throw MappingFailedException::incorrectValue($data, $path, 'float or int with value that can be losslessly converted to float'); + throw MappingFailedException::incorrectValue($data, $context, 'float or int with value that can be losslessly converted to float'); } $mapped = floatval($data); } else { - throw MappingFailedException::incorrectType($data, $path, 'float'); + throw MappingFailedException::incorrectType($data, $context, 'float'); } if (!Floats::isInteger($mapped / 0.01)) { - throw MappingFailedException::incorrectValue($mapped, $path, 'multiple of 0.01'); + throw MappingFailedException::incorrectValue($mapped, $context, 'multiple of 0.01'); } return $mapped; diff --git a/tests/Compiler/Validator/Float/Data/NoopFloatRangeValidatorMapper.php b/tests/Compiler/Validator/Float/Data/NoopFloatRangeValidatorMapper.php index 1ae9aca..6e1b610 100644 --- a/tests/Compiler/Validator/Float/Data/NoopFloatRangeValidatorMapper.php +++ b/tests/Compiler/Validator/Float/Data/NoopFloatRangeValidatorMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function floatval; use function is_finite; @@ -27,25 +28,24 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): float + public function map(mixed $data, ?MapperContext $context = null): float { if (is_float($data)) { if (!is_finite($data)) { - throw MappingFailedException::incorrectType($data, $path, 'finite float'); + throw MappingFailedException::incorrectType($data, $context, 'finite float'); } $mapped = $data; } elseif (is_int($data)) { if ($data < self::MIN_SAFE_INTEGER || $data > self::MAX_SAFE_INTEGER) { - throw MappingFailedException::incorrectValue($data, $path, 'float or int with value that can be losslessly converted to float'); + throw MappingFailedException::incorrectValue($data, $context, 'float or int with value that can be losslessly converted to float'); } $mapped = floatval($data); } else { - throw MappingFailedException::incorrectType($data, $path, 'float'); + throw MappingFailedException::incorrectType($data, $context, 'float'); } return $mapped; diff --git a/tests/Compiler/Validator/Int/Data/IntMultipleOfFiveMapper.php b/tests/Compiler/Validator/Int/Data/IntMultipleOfFiveMapper.php index 15dd9bc..c64fa8b 100644 --- a/tests/Compiler/Validator/Int/Data/IntMultipleOfFiveMapper.php +++ b/tests/Compiler/Validator/Int/Data/IntMultipleOfFiveMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_int; @@ -20,17 +21,16 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): int + public function map(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } if ($data % 5 !== 0) { - throw MappingFailedException::incorrectValue($data, $path, 'multiple of 5'); + throw MappingFailedException::incorrectValue($data, $context, 'multiple of 5'); } return $data; diff --git a/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithExclusiveLowerBoundMapper.php b/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithExclusiveLowerBoundMapper.php index 16ac2ad..e82dbdb 100644 --- a/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithExclusiveLowerBoundMapper.php +++ b/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithExclusiveLowerBoundMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_int; @@ -20,18 +21,17 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return int<6, max> * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): int + public function map(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } if ($data <= 5) { - throw MappingFailedException::incorrectValue($data, $path, 'value greater than 5'); + throw MappingFailedException::incorrectValue($data, $context, 'value greater than 5'); } return $data; diff --git a/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithExclusiveUpperBoundMapper.php b/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithExclusiveUpperBoundMapper.php index 6ad5dd1..92d7f1c 100644 --- a/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithExclusiveUpperBoundMapper.php +++ b/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithExclusiveUpperBoundMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_int; @@ -20,18 +21,17 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return int * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): int + public function map(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } if ($data >= 5) { - throw MappingFailedException::incorrectValue($data, $path, 'value less than 5'); + throw MappingFailedException::incorrectValue($data, $context, 'value less than 5'); } return $data; diff --git a/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithInclusiveLowerAndUpperBoundMapper.php b/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithInclusiveLowerAndUpperBoundMapper.php index 3584c66..76a2449 100644 --- a/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithInclusiveLowerAndUpperBoundMapper.php +++ b/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithInclusiveLowerAndUpperBoundMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_int; @@ -20,22 +21,21 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return int<5, 10> * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): int + public function map(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } if ($data < 5) { - throw MappingFailedException::incorrectValue($data, $path, 'value greater than or equal to 5'); + throw MappingFailedException::incorrectValue($data, $context, 'value greater than or equal to 5'); } if ($data > 10) { - throw MappingFailedException::incorrectValue($data, $path, 'value less than or equal to 10'); + throw MappingFailedException::incorrectValue($data, $context, 'value less than or equal to 10'); } return $data; diff --git a/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithInclusiveLowerBoundMapper.php b/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithInclusiveLowerBoundMapper.php index 8f47af5..4684384 100644 --- a/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithInclusiveLowerBoundMapper.php +++ b/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithInclusiveLowerBoundMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_int; @@ -20,18 +21,17 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return int<5, max> * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): int + public function map(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } if ($data < 5) { - throw MappingFailedException::incorrectValue($data, $path, 'value greater than or equal to 5'); + throw MappingFailedException::incorrectValue($data, $context, 'value greater than or equal to 5'); } return $data; diff --git a/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithInclusiveUpperBoundMapper.php b/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithInclusiveUpperBoundMapper.php index c1250dd..a68bcce 100644 --- a/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithInclusiveUpperBoundMapper.php +++ b/tests/Compiler/Validator/Int/Data/IntRangeValidatorWithInclusiveUpperBoundMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_int; @@ -20,18 +21,17 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return int * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): int + public function map(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } if ($data > 5) { - throw MappingFailedException::incorrectValue($data, $path, 'value less than or equal to 5'); + throw MappingFailedException::incorrectValue($data, $context, 'value less than or equal to 5'); } return $data; diff --git a/tests/Compiler/Validator/Int/Data/NonNegativeIntValidatorMapper.php b/tests/Compiler/Validator/Int/Data/NonNegativeIntValidatorMapper.php index 52f0dfe..d1ae32c 100644 --- a/tests/Compiler/Validator/Int/Data/NonNegativeIntValidatorMapper.php +++ b/tests/Compiler/Validator/Int/Data/NonNegativeIntValidatorMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_int; @@ -20,18 +21,17 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return int<0, max> * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): int + public function map(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } if ($data < 0) { - throw MappingFailedException::incorrectValue($data, $path, 'value greater than or equal to 0'); + throw MappingFailedException::incorrectValue($data, $context, 'value greater than or equal to 0'); } return $data; diff --git a/tests/Compiler/Validator/Int/Data/NoopIntRangeValidatorMapper.php b/tests/Compiler/Validator/Int/Data/NoopIntRangeValidatorMapper.php index f57242e..547a412 100644 --- a/tests/Compiler/Validator/Int/Data/NoopIntRangeValidatorMapper.php +++ b/tests/Compiler/Validator/Int/Data/NoopIntRangeValidatorMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_int; @@ -20,13 +21,12 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): int + public function map(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } return $data; diff --git a/tests/Compiler/Validator/Int/Data/PositiveIntValidatorMapper.php b/tests/Compiler/Validator/Int/Data/PositiveIntValidatorMapper.php index 53f94dc..3cd71ac 100644 --- a/tests/Compiler/Validator/Int/Data/PositiveIntValidatorMapper.php +++ b/tests/Compiler/Validator/Int/Data/PositiveIntValidatorMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_int; @@ -20,18 +21,17 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @return positive-int * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): int + public function map(mixed $data, ?MapperContext $context = null): int { if (!is_int($data)) { - throw MappingFailedException::incorrectType($data, $path, 'int'); + throw MappingFailedException::incorrectType($data, $context, 'int'); } if ($data <= 0) { - throw MappingFailedException::incorrectValue($data, $path, 'value greater than 0'); + throw MappingFailedException::incorrectValue($data, $context, 'value greater than 0'); } return $data; diff --git a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithBothDateAndTimeMapper.php b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithBothDateAndTimeMapper.php index f28f67e..8707de9 100644 --- a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithBothDateAndTimeMapper.php +++ b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithBothDateAndTimeMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -21,23 +22,22 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $mapped = DateTimeImmutable::createFromFormat('Y-m-d\\TH:i:sP', $data); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date-time string in RFC 3339 format'); + throw MappingFailedException::incorrectValue($data, $context, 'date-time string in RFC 3339 format'); } if ($mapped < new DateTimeImmutable('2000-01-01T00:00:05Z')) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value greater than or equal to 2000-01-01T00:00:05Z'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value greater than or equal to 2000-01-01T00:00:05Z'); } return $mapped; diff --git a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithExclusiveLowerBoundMapper.php b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithExclusiveLowerBoundMapper.php index 89fb4aa..154d8b6 100644 --- a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithExclusiveLowerBoundMapper.php +++ b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithExclusiveLowerBoundMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -21,23 +22,22 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $mapped = DateTimeImmutable::createFromFormat('!Y-m-d', $data); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date string in Y-m-d format'); + throw MappingFailedException::incorrectValue($data, $context, 'date string in Y-m-d format'); } if ($mapped <= new DateTimeImmutable('2000-01-05')) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value greater than 2000-01-05'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value greater than 2000-01-05'); } return $mapped; diff --git a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithExclusiveUpperBoundMapper.php b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithExclusiveUpperBoundMapper.php index c6b65d7..a0e92c2 100644 --- a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithExclusiveUpperBoundMapper.php +++ b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithExclusiveUpperBoundMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -21,23 +22,22 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $mapped = DateTimeImmutable::createFromFormat('!Y-m-d', $data); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date string in Y-m-d format'); + throw MappingFailedException::incorrectValue($data, $context, 'date string in Y-m-d format'); } if ($mapped >= new DateTimeImmutable('2000-01-05')) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value less than 2000-01-05'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value less than 2000-01-05'); } return $mapped; diff --git a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithInclusiveLowerAndUpperBoundMapper.php b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithInclusiveLowerAndUpperBoundMapper.php index df0dde6..eec365d 100644 --- a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithInclusiveLowerAndUpperBoundMapper.php +++ b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithInclusiveLowerAndUpperBoundMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -21,27 +22,26 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $mapped = DateTimeImmutable::createFromFormat('!Y-m-d', $data); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date string in Y-m-d format'); + throw MappingFailedException::incorrectValue($data, $context, 'date string in Y-m-d format'); } if ($mapped < new DateTimeImmutable('2000-01-05')) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value greater than or equal to 2000-01-05'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value greater than or equal to 2000-01-05'); } if ($mapped > new DateTimeImmutable('2000-01-10')) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value less than or equal to 2000-01-10'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value less than or equal to 2000-01-10'); } return $mapped; diff --git a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithInclusiveLowerBoundMapper.php b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithInclusiveLowerBoundMapper.php index baecc4a..d0a7eae 100644 --- a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithInclusiveLowerBoundMapper.php +++ b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithInclusiveLowerBoundMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -21,23 +22,22 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $mapped = DateTimeImmutable::createFromFormat('!Y-m-d', $data); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date string in Y-m-d format'); + throw MappingFailedException::incorrectValue($data, $context, 'date string in Y-m-d format'); } if ($mapped < new DateTimeImmutable('2000-01-05')) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value greater than or equal to 2000-01-05'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value greater than or equal to 2000-01-05'); } return $mapped; diff --git a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithInclusiveUpperBoundMapper.php b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithInclusiveUpperBoundMapper.php index f550f31..7137ef8 100644 --- a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithInclusiveUpperBoundMapper.php +++ b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithInclusiveUpperBoundMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -21,23 +22,22 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $mapped = DateTimeImmutable::createFromFormat('!Y-m-d', $data); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date string in Y-m-d format'); + throw MappingFailedException::incorrectValue($data, $context, 'date string in Y-m-d format'); } if ($mapped > new DateTimeImmutable('2000-01-05')) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value less than or equal to 2000-01-05'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value less than or equal to 2000-01-05'); } return $mapped; diff --git a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithRelativeBoundMapper.php b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithRelativeBoundMapper.php index 5a58187..e9a2293 100644 --- a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithRelativeBoundMapper.php +++ b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithRelativeBoundMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -21,23 +22,22 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $mapped = DateTimeImmutable::createFromFormat('Y-m-d\\TH:i:sP', $data); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date-time string in RFC 3339 format'); + throw MappingFailedException::incorrectValue($data, $context, 'date-time string in RFC 3339 format'); } if ($mapped < new DateTimeImmutable('now')) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value greater than or equal to now'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value greater than or equal to now'); } return $mapped; diff --git a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithTimezoneMapper.php b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithTimezoneMapper.php index 1e24257..e200ab6 100644 --- a/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithTimezoneMapper.php +++ b/tests/Compiler/Validator/Object/Data/DateTimeRangeValidatorWithTimezoneMapper.php @@ -7,6 +7,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -22,20 +23,19 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $timezone = new DateTimeZone('America/New_York'); $mapped = DateTimeImmutable::createFromFormat('!Y-m-d', $data, $timezone); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date-time string in RFC 3339 format'); + throw MappingFailedException::incorrectValue($data, $context, 'date-time string in RFC 3339 format'); } $timezone2 = new DateTimeZone('America/New_York'); @@ -44,7 +44,7 @@ public function map(mixed $data, array $path = []): DateTimeImmutable '2000-01-05', $timezone2, )) { - throw MappingFailedException::incorrectValue($mapped, $path, 'value greater than or equal to 2000-01-05 (in America/New_York timezone)'); + throw MappingFailedException::incorrectValue($mapped, $context, 'value greater than or equal to 2000-01-05 (in America/New_York timezone)'); } return $mapped; diff --git a/tests/Compiler/Validator/Object/Data/NoopDateTimeRangeValidatorMapper.php b/tests/Compiler/Validator/Object/Data/NoopDateTimeRangeValidatorMapper.php index 8c6c467..5820515 100644 --- a/tests/Compiler/Validator/Object/Data/NoopDateTimeRangeValidatorMapper.php +++ b/tests/Compiler/Validator/Object/Data/NoopDateTimeRangeValidatorMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -21,19 +22,18 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): DateTimeImmutable + public function map(mixed $data, ?MapperContext $context = null): DateTimeImmutable { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } $mapped = DateTimeImmutable::createFromFormat('!Y-m-d', $data); if ($mapped === false) { - throw MappingFailedException::incorrectValue($data, $path, 'date string in Y-m-d format'); + throw MappingFailedException::incorrectValue($data, $context, 'date string in Y-m-d format'); } return $mapped; diff --git a/tests/Compiler/Validator/String/Data/NoopStringLengthValidatorMapper.php b/tests/Compiler/Validator/String/Data/NoopStringLengthValidatorMapper.php index 41a1e04..7e2a32e 100644 --- a/tests/Compiler/Validator/String/Data/NoopStringLengthValidatorMapper.php +++ b/tests/Compiler/Validator/String/Data/NoopStringLengthValidatorMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; use function strlen; @@ -21,13 +22,12 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): string + public function map(mixed $data, ?MapperContext $context = null): string { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } return $data; diff --git a/tests/Compiler/Validator/String/Data/PatternValidatorMapper.php b/tests/Compiler/Validator/String/Data/PatternValidatorMapper.php index 904f5a5..7c9fcf0 100644 --- a/tests/Compiler/Validator/String/Data/PatternValidatorMapper.php +++ b/tests/Compiler/Validator/String/Data/PatternValidatorMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; use function preg_match; @@ -21,17 +22,16 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): string + public function map(mixed $data, ?MapperContext $context = null): string { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } if (preg_match('#^\\d+\\z#', $data) !== 1) { - throw MappingFailedException::incorrectValue($data, $path, 'string matching pattern #^\\d+\\z#'); + throw MappingFailedException::incorrectValue($data, $context, 'string matching pattern #^\\d+\\z#'); } return $data; diff --git a/tests/Compiler/Validator/String/Data/PatternValidatorWithCustomPatternDescriptionMapper.php b/tests/Compiler/Validator/String/Data/PatternValidatorWithCustomPatternDescriptionMapper.php index b9f5430..595e656 100644 --- a/tests/Compiler/Validator/String/Data/PatternValidatorWithCustomPatternDescriptionMapper.php +++ b/tests/Compiler/Validator/String/Data/PatternValidatorWithCustomPatternDescriptionMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; use function preg_match; @@ -21,17 +22,16 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): string + public function map(mixed $data, ?MapperContext $context = null): string { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } if (preg_match('#^\\d+\\z#', $data) !== 1) { - throw MappingFailedException::incorrectValue($data, $path, 'numeric string'); + throw MappingFailedException::incorrectValue($data, $context, 'numeric string'); } return $data; diff --git a/tests/Compiler/Validator/String/Data/StringLengthValidatorWithExactMapper.php b/tests/Compiler/Validator/String/Data/StringLengthValidatorWithExactMapper.php index 6ffbce2..7b41494 100644 --- a/tests/Compiler/Validator/String/Data/StringLengthValidatorWithExactMapper.php +++ b/tests/Compiler/Validator/String/Data/StringLengthValidatorWithExactMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; use function strlen; @@ -21,17 +22,16 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): string + public function map(mixed $data, ?MapperContext $context = null): string { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } if (strlen($data) !== 5) { - throw MappingFailedException::incorrectValue($data, $path, 'string with exactly 5 characters'); + throw MappingFailedException::incorrectValue($data, $context, 'string with exactly 5 characters'); } return $data; diff --git a/tests/Compiler/Validator/String/Data/StringLengthValidatorWithMaxMapper.php b/tests/Compiler/Validator/String/Data/StringLengthValidatorWithMaxMapper.php index a2bb71b..2507038 100644 --- a/tests/Compiler/Validator/String/Data/StringLengthValidatorWithMaxMapper.php +++ b/tests/Compiler/Validator/String/Data/StringLengthValidatorWithMaxMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; use function strlen; @@ -21,17 +22,16 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): string + public function map(mixed $data, ?MapperContext $context = null): string { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } if (strlen($data) > 5) { - throw MappingFailedException::incorrectValue($data, $path, 'string with at most 5 characters'); + throw MappingFailedException::incorrectValue($data, $context, 'string with at most 5 characters'); } return $data; diff --git a/tests/Compiler/Validator/String/Data/StringLengthValidatorWithMinAndMaxMapper.php b/tests/Compiler/Validator/String/Data/StringLengthValidatorWithMinAndMaxMapper.php index 0d3c457..c63fdb1 100644 --- a/tests/Compiler/Validator/String/Data/StringLengthValidatorWithMinAndMaxMapper.php +++ b/tests/Compiler/Validator/String/Data/StringLengthValidatorWithMinAndMaxMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; use function strlen; @@ -21,21 +22,20 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): string + public function map(mixed $data, ?MapperContext $context = null): string { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } if (strlen($data) < 1) { - throw MappingFailedException::incorrectValue($data, $path, 'string with at least 1 characters'); + throw MappingFailedException::incorrectValue($data, $context, 'string with at least 1 characters'); } if (strlen($data) > 5) { - throw MappingFailedException::incorrectValue($data, $path, 'string with at most 5 characters'); + throw MappingFailedException::incorrectValue($data, $context, 'string with at most 5 characters'); } return $data; diff --git a/tests/Compiler/Validator/String/Data/StringLengthValidatorWithMinMapper.php b/tests/Compiler/Validator/String/Data/StringLengthValidatorWithMinMapper.php index 1777831..4c2c676 100644 --- a/tests/Compiler/Validator/String/Data/StringLengthValidatorWithMinMapper.php +++ b/tests/Compiler/Validator/String/Data/StringLengthValidatorWithMinMapper.php @@ -5,6 +5,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; use function strlen; @@ -21,17 +22,16 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): string + public function map(mixed $data, ?MapperContext $context = null): string { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } if (strlen($data) < 5) { - throw MappingFailedException::incorrectValue($data, $path, 'string with at least 5 characters'); + throw MappingFailedException::incorrectValue($data, $context, 'string with at least 5 characters'); } return $data; diff --git a/tests/Compiler/Validator/String/Data/UrlValidatorMapper.php b/tests/Compiler/Validator/String/Data/UrlValidatorMapper.php index 5f816a9..312ae03 100644 --- a/tests/Compiler/Validator/String/Data/UrlValidatorMapper.php +++ b/tests/Compiler/Validator/String/Data/UrlValidatorMapper.php @@ -6,6 +6,7 @@ use ShipMonk\InputMapper\Compiler\Mapper\Wrapper\ValidatedMapperCompiler; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\MapperProvider; use function is_string; @@ -21,17 +22,16 @@ public function __construct(private readonly MapperProvider $provider) } /** - * @param list $path * @throws MappingFailedException */ - public function map(mixed $data, array $path = []): string + public function map(mixed $data, ?MapperContext $context = null): string { if (!is_string($data)) { - throw MappingFailedException::incorrectType($data, $path, 'string'); + throw MappingFailedException::incorrectType($data, $context, 'string'); } if (!Validators::isUrl($data)) { - throw MappingFailedException::incorrectValue($data, $path, 'valid URL'); + throw MappingFailedException::incorrectValue($data, $context, 'valid URL'); } return $data; diff --git a/tests/Runtime/Data/DummyMapper.php b/tests/Runtime/Data/DummyMapper.php index 5a78c05..419e708 100644 --- a/tests/Runtime/Data/DummyMapper.php +++ b/tests/Runtime/Data/DummyMapper.php @@ -3,6 +3,7 @@ namespace ShipMonkTests\InputMapper\Runtime\Data; use ShipMonk\InputMapper\Runtime\Mapper; +use ShipMonk\InputMapper\Runtime\MapperContext; /** * @implements Mapper @@ -10,10 +11,7 @@ class DummyMapper implements Mapper { - /** - * @param list $path - */ - public function map(mixed $data, array $path = []): mixed + public function map(mixed $data, ?MapperContext $context = null): mixed { return $data; } diff --git a/tests/Runtime/Exception/MappingFailedExceptionTest.php b/tests/Runtime/Exception/MappingFailedExceptionTest.php index 646837a..b2ac454 100644 --- a/tests/Runtime/Exception/MappingFailedExceptionTest.php +++ b/tests/Runtime/Exception/MappingFailedExceptionTest.php @@ -6,6 +6,7 @@ use DateTimeZone; use PHPUnit\Framework\Attributes\DataProvider; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonkTests\InputMapper\InputMapperTestCase; use stdClass; use function str_repeat; @@ -26,93 +27,95 @@ public function testMessages(MappingFailedException $exception, string $expected */ public static function provideMessagesData(): iterable { + $context = new MapperContext(null, 'foo'); + yield 'null' => [ - MappingFailedException::incorrectValue(null, ['foo'], 'int'), + MappingFailedException::incorrectValue(null, $context, 'int'), 'Failed to map data at path /foo: Expected int, got null', ]; yield 'true' => [ - MappingFailedException::incorrectValue(true, ['foo'], 'int'), + MappingFailedException::incorrectValue(true, $context, 'int'), 'Failed to map data at path /foo: Expected int, got true', ]; yield '123' => [ - MappingFailedException::incorrectValue(123, ['foo'], 'string'), + MappingFailedException::incorrectValue(123, $context, 'string'), 'Failed to map data at path /foo: Expected string, got 123', ]; yield '1.23' => [ - MappingFailedException::incorrectValue(1.23, ['foo'], 'string'), + MappingFailedException::incorrectValue(1.23, $context, 'string'), 'Failed to map data at path /foo: Expected string, got 1.23', ]; yield '1.0' => [ - MappingFailedException::incorrectValue(1.0, ['foo'], 'string'), + MappingFailedException::incorrectValue(1.0, $context, 'string'), 'Failed to map data at path /foo: Expected string, got 1.0', ]; yield 'INF' => [ - MappingFailedException::incorrectValue(INF, ['foo'], 'string'), + MappingFailedException::incorrectValue(INF, $context, 'string'), 'Failed to map data at path /foo: Expected string, got INF', ]; yield 'NAN' => [ - MappingFailedException::incorrectValue(NAN, ['foo'], 'string'), + MappingFailedException::incorrectValue(NAN, $context, 'string'), 'Failed to map data at path /foo: Expected string, got NAN', ]; yield 'short string' => [ - MappingFailedException::incorrectValue('short string', ['foo'], 'int'), + MappingFailedException::incorrectValue('short string', $context, 'int'), 'Failed to map data at path /foo: Expected int, got "short string"', ]; yield 'long string' => [ - MappingFailedException::incorrectValue(str_repeat('a', 1_000), ['foo'], 'int'), + MappingFailedException::incorrectValue(str_repeat('a', 1_000), $context, 'int'), 'Failed to map data at path /foo: Expected int, got "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" (truncated)', ]; yield 'string with slash' => [ - MappingFailedException::incorrectValue('foo/bar', ['foo'], 'int'), + MappingFailedException::incorrectValue('foo/bar', $context, 'int'), 'Failed to map data at path /foo: Expected int, got "foo/bar"', ]; yield 'string with control characters' => [ - MappingFailedException::incorrectValue("foo\x00bar", ['foo'], 'int'), + MappingFailedException::incorrectValue("foo\x00bar", $context, 'int'), 'Failed to map data at path /foo: Expected int, got string', ]; yield 'string with invalid UTF-8' => [ - MappingFailedException::incorrectValue("foo\x80bar", ['foo'], 'int'), + MappingFailedException::incorrectValue("foo\x80bar", $context, 'int'), 'Failed to map data at path /foo: Expected int, got string', ]; yield 'array' => [ - MappingFailedException::incorrectValue([], ['foo'], 'int'), + MappingFailedException::incorrectValue([], $context, 'int'), 'Failed to map data at path /foo: Expected int, got array', ]; yield 'date UTC' => [ - MappingFailedException::incorrectValue(new DateTimeImmutable('2023-05-25'), ['foo'], 'int'), + MappingFailedException::incorrectValue(new DateTimeImmutable('2023-05-25'), $context, 'int'), 'Failed to map data at path /foo: Expected int, got 2023-05-25 (UTC)', ]; yield 'date Prague' => [ - MappingFailedException::incorrectValue(new DateTimeImmutable('2023-05-25', new DateTimeZone('Europe/Prague')), ['foo'], 'int'), + MappingFailedException::incorrectValue(new DateTimeImmutable('2023-05-25', new DateTimeZone('Europe/Prague')), $context, 'int'), 'Failed to map data at path /foo: Expected int, got 2023-05-25 (Europe/Prague)', ]; yield 'datetime UTC' => [ - MappingFailedException::incorrectValue(new DateTimeImmutable('2023-05-25T12:14:15'), ['foo'], 'int'), + MappingFailedException::incorrectValue(new DateTimeImmutable('2023-05-25T12:14:15'), $context, 'int'), 'Failed to map data at path /foo: Expected int, got 2023-05-25T12:14:15+00:00', ]; yield 'datetime Prague' => [ - MappingFailedException::incorrectValue(new DateTimeImmutable('2023-05-25T12:14:15', new DateTimeZone('Europe/Prague')), ['foo'], 'int'), + MappingFailedException::incorrectValue(new DateTimeImmutable('2023-05-25T12:14:15', new DateTimeZone('Europe/Prague')), $context, 'int'), 'Failed to map data at path /foo: Expected int, got 2023-05-25T12:14:15+02:00', ]; yield 'object' => [ - MappingFailedException::incorrectValue(new stdClass(), ['foo'], 'int'), + MappingFailedException::incorrectValue(new stdClass(), $context, 'int'), 'Failed to map data at path /foo: Expected int, got stdClass', ]; } diff --git a/tests/Runtime/MapperProviderTest.php b/tests/Runtime/MapperProviderTest.php index ba1c9bd..a942e51 100644 --- a/tests/Runtime/MapperProviderTest.php +++ b/tests/Runtime/MapperProviderTest.php @@ -68,7 +68,7 @@ public function testMapperForOptionalNotNullInput(): void $mapperProvider = $this->createMapperProvider(); $mapper = $mapperProvider->get(OptionalNotNullInput::class); self::assertEquals(new OptionalNotNullInput(Optional::of(123)), $mapper->map(['number' => 123])); - self::assertEquals(new OptionalNotNullInput(Optional::none([], 'number')), $mapper->map([])); + self::assertEquals(new OptionalNotNullInput(Optional::none(null, 'number')), $mapper->map([])); self::assertException( MappingFailedException::class, @@ -93,7 +93,7 @@ public function testMapperForOptionalNullableInput(): void $mapper = $mapperProvider->get(OptionalNullableInput::class); self::assertEquals(new OptionalNullableInput(Optional::of(123)), $mapper->map(['number' => 123])); self::assertEquals(new OptionalNullableInput(Optional::of(null)), $mapper->map(['number' => null])); - self::assertEquals(new OptionalNullableInput(Optional::none([], 'number')), $mapper->map([])); + self::assertEquals(new OptionalNullableInput(Optional::none(null, 'number')), $mapper->map([])); self::assertException( MappingFailedException::class, diff --git a/tests/Runtime/OptionalNoneTest.php b/tests/Runtime/OptionalNoneTest.php index bb49906..60bc703 100644 --- a/tests/Runtime/OptionalNoneTest.php +++ b/tests/Runtime/OptionalNoneTest.php @@ -4,6 +4,7 @@ use LogicException; use ShipMonk\InputMapper\Runtime\Exception\MappingFailedException; +use ShipMonk\InputMapper\Runtime\MapperContext; use ShipMonk\InputMapper\Runtime\Optional; use ShipMonkTests\InputMapper\InputMapperTestCase; @@ -12,7 +13,7 @@ class OptionalNoneTest extends InputMapperTestCase public function testIsDefined(): void { - self::assertFalse(Optional::none([], 'key')->isDefined()); + self::assertFalse(Optional::none(null, 'key')->isDefined()); } public function testGet(): void @@ -21,7 +22,7 @@ public function testGet(): void LogicException::class, 'Optional is not defined', static function (): void { - Optional::none([], 'key')->get(); + Optional::none(null, 'key')->get(); }, ); } @@ -32,7 +33,7 @@ public function testRequire(): void MappingFailedException::class, 'Failed to map data at path /: Missing required key "key"', static function (): void { - Optional::none([], 'key')->require(); + Optional::none(null, 'key')->require(); }, ); @@ -40,7 +41,7 @@ static function (): void { MappingFailedException::class, 'Failed to map data at path /foo: Missing required key "bar"', static function (): void { - Optional::none(['foo'], 'bar')->require(); + Optional::none(MapperContext::fromPath(['foo']), 'bar')->require(); }, ); } @@ -48,7 +49,7 @@ static function (): void { public function testGetOrElse(): void { // @phpstan-ignore-next-line always true - self::assertSame('default', Optional::none([], 'key')->getOrElse('default')); + self::assertSame('default', Optional::none(null, 'key')->getOrElse('default')); } }