40
40
use ShipMonk \InputMapper \Compiler \Mapper \Object \MapDateTimeImmutable ;
41
41
use ShipMonk \InputMapper \Compiler \Mapper \Object \MapEnum ;
42
42
use ShipMonk \InputMapper \Compiler \Mapper \Object \MapObject ;
43
+ use ShipMonk \InputMapper \Compiler \Mapper \Optional as OptionalAttribute ;
43
44
use ShipMonk \InputMapper \Compiler \Mapper \Scalar \MapBool ;
44
45
use ShipMonk \InputMapper \Compiler \Mapper \Scalar \MapFloat ;
45
46
use ShipMonk \InputMapper \Compiler \Mapper \Scalar \MapInt ;
46
47
use ShipMonk \InputMapper \Compiler \Mapper \Scalar \MapString ;
48
+ use ShipMonk \InputMapper \Compiler \Mapper \UndefinedAwareMapperCompiler ;
47
49
use ShipMonk \InputMapper \Compiler \Mapper \Wrapper \ChainMapperCompiler ;
50
+ use ShipMonk \InputMapper \Compiler \Mapper \Wrapper \MapDefaultValue ;
48
51
use ShipMonk \InputMapper \Compiler \Mapper \Wrapper \MapNullable ;
49
52
use ShipMonk \InputMapper \Compiler \Mapper \Wrapper \MapOptional ;
50
53
use ShipMonk \InputMapper \Compiler \Mapper \Wrapper \ValidatedMapperCompiler ;
@@ -74,6 +77,7 @@ class DefaultMapperCompilerFactory implements MapperCompilerFactory
74
77
75
78
final public const DELEGATE_OBJECT_MAPPING = 'delegateObjectMapping ' ;
76
79
final public const GENERIC_PARAMETERS = 'genericParameters ' ;
80
+ final public const DEFAULT_VALUE = 'defaultValue ' ;
77
81
78
82
/**
79
83
* @param array<class-string, callable(class-string, array<string, mixed>): MapperCompiler> $mapperCompilerFactories
@@ -213,7 +217,7 @@ public function create(TypeNode $type, array $options = []): MapperCompiler
213
217
}
214
218
215
219
if ($ isNullable && count ($ subTypesWithoutNull ) === 1 ) {
216
- return new MapNullable ( $ this ->createInner ( $ subTypesWithoutNull [0 ], $ options) );
220
+ return $ this ->create ( new NullableTypeNode ( $ subTypesWithoutNull [0 ]) , $ options );
217
221
}
218
222
}
219
223
@@ -396,10 +400,20 @@ protected function createParameterMapperCompiler(
396
400
default => new ChainMapperCompiler ($ mappers ),
397
401
};
398
402
403
+ foreach ($ parameterReflection ->getAttributes (OptionalAttribute::class, ReflectionAttribute::IS_INSTANCEOF ) as $ attribute ) {
404
+ $ mapper = new MapDefaultValue ($ mapper , $ attribute ->newInstance ()->default );
405
+ }
406
+
399
407
if (!PhpDocTypeUtils::isSubTypeOf ($ mapper ->getOutputType (), $ type )) {
400
408
throw CannotCreateMapperCompilerException::withIncompatibleMapperForMethodParameter ($ mapper , $ parameterReflection , $ type );
401
409
}
402
410
411
+ if ($ mapper instanceof UndefinedAwareMapperCompiler) {
412
+ if (!PhpDocTypeUtils::isSubTypeOf ($ mapper ->getDefaultValueType (), $ type )) {
413
+ throw CannotCreateMapperCompilerException::withIncompatibleDefaultValueParameter ($ mapper , $ parameterReflection , $ type );
414
+ }
415
+ }
416
+
403
417
foreach ($ validators as $ validator ) {
404
418
$ mapper = $ this ->addValidator ($ mapper , $ validator );
405
419
}
@@ -419,6 +433,10 @@ protected function addValidator(
419
433
return new ValidatedMapperCompiler ($ mapperCompiler , [$ validatorCompiler ]);
420
434
}
421
435
436
+ if ($ mapperCompiler instanceof MapDefaultValue) {
437
+ return new MapDefaultValue ($ this ->addValidator ($ mapperCompiler ->mapperCompiler , $ validatorCompiler ), $ mapperCompiler ->defaultValue );
438
+ }
439
+
422
440
if ($ mapperCompiler instanceof MapNullable) {
423
441
return new MapNullable ($ this ->addValidator ($ mapperCompiler ->innerMapperCompiler , $ validatorCompiler ));
424
442
}
0 commit comments