3 declare(strict_types=1);
5 namespace CuyZ\Valinor\Mapper\Object\Factory;
7 use CuyZ\Valinor\Definition\ClassDefinition;
8 use CuyZ\Valinor\Definition\FunctionObject;
9 use CuyZ\Valinor\Definition\Repository\FunctionDefinitionRepository;
10 use CuyZ\Valinor\Mapper\Object\DateTimeFormatConstructor;
11 use CuyZ\Valinor\Mapper\Object\FunctionObjectBuilder;
12 use CuyZ\Valinor\Mapper\Object\NativeConstructorObjectBuilder;
13 use CuyZ\Valinor\Mapper\Object\ObjectBuilder;
14 use CuyZ\Valinor\Type\ClassType;
16 use DateTimeImmutable;
18 use function array_filter;
22 final class DateTimeObjectBuilderFactory implements ObjectBuilderFactory
24 public function __construct(
25 private ObjectBuilderFactory $delegate,
26 private FunctionDefinitionRepository $functionDefinitionRepository
30 public function for(ClassDefinition $class): array
32 $className = $class->name();
34 $builders = $this->delegate->for($class);
36 if ($className !== DateTime::class && $className !== DateTimeImmutable::class) {
40 // Remove `DateTime` & `DateTimeImmutable` native constructors
41 $builders = array_filter($builders, fn (ObjectBuilder $builder) => ! $builder instanceof NativeConstructorObjectBuilder);
43 $useDefaultBuilder = true;
45 foreach ($builders as $builder) {
46 if (count($builder->describeArguments()) === 1) {
47 $useDefaultBuilder = false;
48 // @infection-ignore-all
53 if ($useDefaultBuilder) {
54 // @infection-ignore-all / Ignore memoization
55 $builders[] = $this->defaultBuilder($class->type());
61 private function defaultBuilder(ClassType $type): FunctionObjectBuilder
63 $constructor = new DateTimeFormatConstructor(DATE_ATOM, 'U');
64 $function = new FunctionObject($this->functionDefinitionRepository->for($constructor), $constructor);
66 return new FunctionObjectBuilder($function, $type);