feat: add multiple Types support

This commit is contained in:
Victor Westerlund 2023-11-29 08:20:35 +01:00
parent c70a46568e
commit 47987b9d97
2 changed files with 35 additions and 20 deletions

View file

@ -22,7 +22,11 @@
private string $property;
public bool $required = false;
public ?Type $type = null;
// Matched Type against $types array
private ?Type $type = null;
// Typed array of type ReflectRules\Type
public ?array $types = null;
private bool $default_enabled = false;
public mixed $default;
@ -68,14 +72,9 @@
return $this;
}
// Set property Type
public function type(Type|string $type): self {
// Coerce string to Type enum
if (!($type instanceof Type)) {
$type = Type::fromName($string);
}
$this->type = $type;
// Set property Types
public function type(Type $type): self {
$this->types[] = $type;
return $this;
}
@ -144,15 +143,28 @@
}
public function eval_type(mixed $value, Scope $scope): bool {
return match($this->type) {
Type::NUMBER => is_numeric($value),
Type::STRING => is_string($value),
Type::BOOLEAN => $this->eval_type_boolean($value, $scope),
Type::ARRAY,
Type::OBJECT => is_array($value),
Type::NULL => is_null($value),
default => true
};
$match = false;
foreach ($this->types as $type) {
match($type) {
Type::NUMBER => $match = is_numeric($value),
Type::STRING => $match = is_string($value),
Type::BOOLEAN => $match = $this->eval_type_boolean($value, $scope),
Type::ARRAY,
Type::OBJECT => $match = is_array($value),
Type::NULL => $match = is_null($value)
};
// Found a matching type
if ($match) {
// Set the matched Type for use in other rules
$this->type = $type;
return true;
}
}
// No matching types were found
return false;
}
public function eval_min(mixed $value, Scope $scope): bool {

View file

@ -80,8 +80,11 @@
The error messages will be returned
*/
if ($rules->type && !$rules->eval_type($value, $scope)) {
$this->add_error($name, "Value must be of type '{$rules->type->name}'");
if ($rules->types && !$rules->eval_type($value, $scope)) {
// List names of each allowed type
$types = implode(" or ", array_map(fn($type): string => $type->name, $rules->types));
$this->add_error($name, "Value must be of type {$types}");
}
if ($rules->min && !$rules->eval_min($value, $scope)) {