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\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 = 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

View File

@ -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

View File

@ -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

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
{
$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\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(