misc: refactor arguments instantiation

This commit is contained in:
Romain Canon 2022-08-05 18:51:25 +02:00
parent b3cb5927e9
commit 6414e9cf14
5 changed files with 71 additions and 54 deletions

View File

@ -6,7 +6,16 @@ namespace CuyZ\Valinor\Mapper\Object;
use CuyZ\Valinor\Definition\Attributes; use CuyZ\Valinor\Definition\Attributes;
use CuyZ\Valinor\Definition\EmptyAttributes; use CuyZ\Valinor\Definition\EmptyAttributes;
use CuyZ\Valinor\Definition\ParameterDefinition;
use CuyZ\Valinor\Definition\PropertyDefinition;
use CuyZ\Valinor\Type\Type; 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 */ /** @internal */
final class Argument final class Argument
@ -28,29 +37,48 @@ final class Argument
$this->type = $type; $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
),
)
));
} }
/** public static function fromParameter(ParameterDefinition $parameter): self
* @param mixed $defaultValue
*/
public static function optional(string $name, Type $type, $defaultValue): self
{ {
$instance = new self($name, $type); $instance = new self($parameter->name(), $parameter->type());
$instance->defaultValue = $defaultValue; $instance->attributes = $parameter->attributes();
$instance->isRequired = false;
if ($parameter->isOptional()) {
$instance->defaultValue = $parameter->defaultValue();
$instance->isRequired = false;
}
return $instance; return $instance;
} }
public function withAttributes(Attributes $attributes): self public static function fromProperty(PropertyDefinition $property): self
{ {
$clone = clone $this; $instance = new self($property->name(), $property->type());
$clone->attributes = $attributes; $instance->attributes = $property->attributes();
return $clone; if ($property->hasDefaultValue()) {
$instance->defaultValue = $property->defaultValue();
$instance->isRequired = false;
}
return $instance;
} }
public function name(): string public function name(): string

View File

@ -33,24 +33,18 @@ final class Arguments implements IteratorAggregate, Countable
public static function fromParameters(Parameters $parameters): self public static function fromParameters(Parameters $parameters): self
{ {
return new self(...array_map(function (ParameterDefinition $parameter) { return new self(...array_map(
$argument = $parameter->isOptional() fn (ParameterDefinition $parameter) => Argument::fromParameter($parameter),
? Argument::optional($parameter->name(), $parameter->type(), $parameter->defaultValue()) array_values(iterator_to_array($parameters)) // @PHP8.1 array unpacking
: Argument::required($parameter->name(), $parameter->type()); ));
return $argument->withAttributes($parameter->attributes());
}, array_values(iterator_to_array($parameters)))); // @PHP8.1 array unpacking
} }
public static function fromProperties(Properties $properties): self public static function fromProperties(Properties $properties): self
{ {
return new self(...array_map(function (PropertyDefinition $property) { return new self(...array_map(
$argument = $property->hasDefaultValue() fn (PropertyDefinition $property) => Argument::fromProperty($property),
? Argument::optional($property->name(), $property->type(), $property->defaultValue()) array_values(iterator_to_array($properties)) // @PHP8.1 array unpacking
: Argument::required($property->name(), $property->type()); ));
return $argument->withAttributes($property->attributes());
}, array_values(iterator_to_array($properties)))); // @PHP8.1 array unpacking
} }
public function at(int $index): Argument public function at(int $index): Argument

View File

@ -5,13 +5,6 @@ declare(strict_types=1);
namespace CuyZ\Valinor\Mapper\Object; namespace CuyZ\Valinor\Mapper\Object;
use CuyZ\Valinor\Mapper\Object\Exception\CannotParseToDateTime; 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 DateTime;
use DateTimeImmutable; use DateTimeImmutable;
use DateTimeInterface; use DateTimeInterface;
@ -44,22 +37,7 @@ final class DateTimeObjectBuilder implements ObjectBuilder
public function describeArguments(): Arguments public function describeArguments(): Arguments
{ {
return $this->arguments ??= new Arguments( return $this->arguments ??= new Arguments(Argument::forDateTime());
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
),
)
))
);
} }
public function build(array $arguments): DateTimeInterface public function build(array $arguments): DateTimeInterface

View File

@ -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 public static function fromReflection(ReflectionParameter $reflection): ParameterDefinition
{ {
$type = new FakeType(); $type = new FakeType();

View File

@ -6,6 +6,7 @@ namespace CuyZ\Valinor\Tests\Unit\Utility;
use CuyZ\Valinor\Mapper\Object\Argument; use CuyZ\Valinor\Mapper\Object\Argument;
use CuyZ\Valinor\Mapper\Object\Arguments; 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\FakeObjectType;
use CuyZ\Valinor\Tests\Fake\Type\FakeType; use CuyZ\Valinor\Tests\Fake\Type\FakeType;
use CuyZ\Valinor\Type\Types\UnionType; use CuyZ\Valinor\Type\Types\UnionType;
@ -22,10 +23,10 @@ final class TypeHelperTest extends TestCase
$typeD = FakeType::permissive(); $typeD = FakeType::permissive();
$arguments = new Arguments( $arguments = new Arguments(
Argument::required('someArgument', $typeA), Argument::fromParameter(FakeParameterDefinition::new('someArgument', $typeA)),
Argument::required('someArgumentOfObject', $typeB), Argument::fromParameter(FakeParameterDefinition::new('someArgumentOfObject', $typeB)),
Argument::required('someArgumentWithUnionOfObject', $typeC), Argument::fromParameter(FakeParameterDefinition::new('someArgumentWithUnionOfObject', $typeC)),
Argument::optional('someOptionalArgument', $typeD, 'defaultValue') Argument::fromParameter(FakeParameterDefinition::optional('someOptionalArgument', $typeD, 'defaultValue')),
); );
self::assertSame( self::assertSame(