diff --git a/src/Mapper/Object/Argument.php b/src/Mapper/Object/Argument.php index 2dd67fe..74f1a4c 100644 --- a/src/Mapper/Object/Argument.php +++ b/src/Mapper/Object/Argument.php @@ -6,7 +6,16 @@ namespace CuyZ\Valinor\Mapper\Object; use CuyZ\Valinor\Definition\Attributes; use CuyZ\Valinor\Definition\EmptyAttributes; +use CuyZ\Valinor\Definition\ParameterDefinition; +use CuyZ\Valinor\Definition\PropertyDefinition; use CuyZ\Valinor\Type\Type; +use CuyZ\Valinor\Type\Types\NonEmptyStringType; +use CuyZ\Valinor\Type\Types\NullType; +use CuyZ\Valinor\Type\Types\PositiveIntegerType; +use CuyZ\Valinor\Type\Types\ShapedArrayElement; +use CuyZ\Valinor\Type\Types\ShapedArrayType; +use CuyZ\Valinor\Type\Types\StringValueType; +use CuyZ\Valinor\Type\Types\UnionType; /** @internal */ final class Argument @@ -28,29 +37,48 @@ final class Argument $this->type = $type; } - public static function required(string $name, Type $type): self + public static function forDateTime(): self { - return new self($name, $type); + return new self('value', new UnionType( + new UnionType(PositiveIntegerType::get(), NonEmptyStringType::get()), + new ShapedArrayType( + new ShapedArrayElement( + new StringValueType('datetime'), + new UnionType(PositiveIntegerType::get(), NonEmptyStringType::get()) + ), + new ShapedArrayElement( + new StringValueType('format'), + new UnionType(NullType::get(), NonEmptyStringType::get()), + true + ), + ) + )); } - /** - * @param mixed $defaultValue - */ - public static function optional(string $name, Type $type, $defaultValue): self + public static function fromParameter(ParameterDefinition $parameter): self { - $instance = new self($name, $type); - $instance->defaultValue = $defaultValue; - $instance->isRequired = false; + $instance = new self($parameter->name(), $parameter->type()); + $instance->attributes = $parameter->attributes(); + + if ($parameter->isOptional()) { + $instance->defaultValue = $parameter->defaultValue(); + $instance->isRequired = false; + } return $instance; } - public function withAttributes(Attributes $attributes): self + public static function fromProperty(PropertyDefinition $property): self { - $clone = clone $this; - $clone->attributes = $attributes; + $instance = new self($property->name(), $property->type()); + $instance->attributes = $property->attributes(); - return $clone; + if ($property->hasDefaultValue()) { + $instance->defaultValue = $property->defaultValue(); + $instance->isRequired = false; + } + + return $instance; } public function name(): string diff --git a/src/Mapper/Object/Arguments.php b/src/Mapper/Object/Arguments.php index e6a8ef3..8b3493d 100644 --- a/src/Mapper/Object/Arguments.php +++ b/src/Mapper/Object/Arguments.php @@ -33,24 +33,18 @@ final class Arguments implements IteratorAggregate, Countable public static function fromParameters(Parameters $parameters): self { - return new self(...array_map(function (ParameterDefinition $parameter) { - $argument = $parameter->isOptional() - ? Argument::optional($parameter->name(), $parameter->type(), $parameter->defaultValue()) - : Argument::required($parameter->name(), $parameter->type()); - - return $argument->withAttributes($parameter->attributes()); - }, array_values(iterator_to_array($parameters)))); // @PHP8.1 array unpacking + return new self(...array_map( + fn (ParameterDefinition $parameter) => Argument::fromParameter($parameter), + array_values(iterator_to_array($parameters)) // @PHP8.1 array unpacking + )); } public static function fromProperties(Properties $properties): self { - return new self(...array_map(function (PropertyDefinition $property) { - $argument = $property->hasDefaultValue() - ? Argument::optional($property->name(), $property->type(), $property->defaultValue()) - : Argument::required($property->name(), $property->type()); - - return $argument->withAttributes($property->attributes()); - }, array_values(iterator_to_array($properties)))); // @PHP8.1 array unpacking + return new self(...array_map( + fn (PropertyDefinition $property) => Argument::fromProperty($property), + array_values(iterator_to_array($properties)) // @PHP8.1 array unpacking + )); } public function at(int $index): Argument diff --git a/src/Mapper/Object/DateTimeObjectBuilder.php b/src/Mapper/Object/DateTimeObjectBuilder.php index fc83ede..747ddf6 100644 --- a/src/Mapper/Object/DateTimeObjectBuilder.php +++ b/src/Mapper/Object/DateTimeObjectBuilder.php @@ -5,13 +5,6 @@ declare(strict_types=1); namespace CuyZ\Valinor\Mapper\Object; use CuyZ\Valinor\Mapper\Object\Exception\CannotParseToDateTime; -use CuyZ\Valinor\Type\Types\NonEmptyStringType; -use CuyZ\Valinor\Type\Types\NullType; -use CuyZ\Valinor\Type\Types\PositiveIntegerType; -use CuyZ\Valinor\Type\Types\ShapedArrayElement; -use CuyZ\Valinor\Type\Types\ShapedArrayType; -use CuyZ\Valinor\Type\Types\StringValueType; -use CuyZ\Valinor\Type\Types\UnionType; use DateTime; use DateTimeImmutable; use DateTimeInterface; @@ -44,22 +37,7 @@ final class DateTimeObjectBuilder implements ObjectBuilder public function describeArguments(): Arguments { - return $this->arguments ??= new Arguments( - Argument::required('value', new UnionType( - new UnionType(PositiveIntegerType::get(), NonEmptyStringType::get()), - new ShapedArrayType( - new ShapedArrayElement( - new StringValueType('datetime'), - new UnionType(PositiveIntegerType::get(), NonEmptyStringType::get()) - ), - new ShapedArrayElement( - new StringValueType('format'), - new UnionType(NullType::get(), NonEmptyStringType::get()), - true - ), - ) - )) - ); + return $this->arguments ??= new Arguments(Argument::forDateTime()); } public function build(array $arguments): DateTimeInterface diff --git a/tests/Fake/Definition/FakeParameterDefinition.php b/tests/Fake/Definition/FakeParameterDefinition.php index a3d4cdd..ed82e10 100644 --- a/tests/Fake/Definition/FakeParameterDefinition.php +++ b/tests/Fake/Definition/FakeParameterDefinition.php @@ -28,6 +28,22 @@ final class FakeParameterDefinition ); } + /** + * @param mixed $defaultValue + */ + public static function optional(string $name, Type $type, $defaultValue): ParameterDefinition + { + return new ParameterDefinition( + $name, + $name, + $type, + true, + false, + $defaultValue, + new FakeAttributes() + ); + } + public static function fromReflection(ReflectionParameter $reflection): ParameterDefinition { $type = new FakeType(); diff --git a/tests/Unit/Utility/TypeHelperTest.php b/tests/Unit/Utility/TypeHelperTest.php index 72811dc..f509b1c 100644 --- a/tests/Unit/Utility/TypeHelperTest.php +++ b/tests/Unit/Utility/TypeHelperTest.php @@ -6,6 +6,7 @@ namespace CuyZ\Valinor\Tests\Unit\Utility; use CuyZ\Valinor\Mapper\Object\Argument; use CuyZ\Valinor\Mapper\Object\Arguments; +use CuyZ\Valinor\Tests\Fake\Definition\FakeParameterDefinition; use CuyZ\Valinor\Tests\Fake\Type\FakeObjectType; use CuyZ\Valinor\Tests\Fake\Type\FakeType; use CuyZ\Valinor\Type\Types\UnionType; @@ -22,10 +23,10 @@ final class TypeHelperTest extends TestCase $typeD = FakeType::permissive(); $arguments = new Arguments( - Argument::required('someArgument', $typeA), - Argument::required('someArgumentOfObject', $typeB), - Argument::required('someArgumentWithUnionOfObject', $typeC), - Argument::optional('someOptionalArgument', $typeD, 'defaultValue') + Argument::fromParameter(FakeParameterDefinition::new('someArgument', $typeA)), + Argument::fromParameter(FakeParameterDefinition::new('someArgumentOfObject', $typeB)), + Argument::fromParameter(FakeParameterDefinition::new('someArgumentWithUnionOfObject', $typeC)), + Argument::fromParameter(FakeParameterDefinition::optional('someOptionalArgument', $typeD, 'defaultValue')), ); self::assertSame(