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; private string $property;
public bool $required = false; 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; private bool $default_enabled = false;
public mixed $default; public mixed $default;
@ -68,14 +72,9 @@
return $this; return $this;
} }
// Set property Type // Set property Types
public function type(Type|string $type): self { public function type(Type $type): self {
// Coerce string to Type enum $this->types[] = $type;
if (!($type instanceof Type)) {
$type = Type::fromName($string);
}
$this->type = $type;
return $this; return $this;
} }
@ -144,15 +143,28 @@
} }
public function eval_type(mixed $value, Scope $scope): bool { public function eval_type(mixed $value, Scope $scope): bool {
return match($this->type) { $match = false;
Type::NUMBER => is_numeric($value),
Type::STRING => is_string($value), foreach ($this->types as $type) {
Type::BOOLEAN => $this->eval_type_boolean($value, $scope), match($type) {
Type::ARRAY, Type::NUMBER => $match = is_numeric($value),
Type::OBJECT => is_array($value), Type::STRING => $match = is_string($value),
Type::NULL => is_null($value), Type::BOOLEAN => $match = $this->eval_type_boolean($value, $scope),
default => true 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 { public function eval_min(mixed $value, Scope $scope): bool {

View file

@ -80,8 +80,11 @@
The error messages will be returned The error messages will be returned
*/ */
if ($rules->type && !$rules->eval_type($value, $scope)) { if ($rules->types && !$rules->eval_type($value, $scope)) {
$this->add_error($name, "Value must be of type '{$rules->type->name}'"); // 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)) { if ($rules->min && !$rules->eval_min($value, $scope)) {