From f0377726d5078e8373cf9146c122a1b014826391 Mon Sep 17 00:00:00 2001 From: Victor Westerlund Date: Wed, 29 Nov 2023 08:56:14 +0100 Subject: [PATCH] feat: add Type::ENUM as type constraint --- src/Rules.php | 22 +++++++++++++++++----- src/Ruleset.php | 8 +++++++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/Rules.php b/src/Rules.php index a08ca59..ca28972 100644 --- a/src/Rules.php +++ b/src/Rules.php @@ -10,12 +10,13 @@ enum Type { use xEnum; + case NULL; + case ENUM; + case ARRAY; case NUMBER; case STRING; - case BOOLEAN; - case ARRAY; case OBJECT; - case NULL; + case BOOLEAN; } class Rules { @@ -28,6 +29,8 @@ // Typed array of type ReflectRules\Type public ?array $types = null; + public ?array $enum = null; + private bool $default_enabled = false; public mixed $default; @@ -72,8 +75,12 @@ return $this; } - // Set property Types - public function type(Type $type): self { + // Add Type constraint with optional argument + public function type(Type $type, mixed $arg = null): self { + if ($type === Type::ENUM) { + $this->enum = $arg; + } + $this->types[] = $type; return $this; } @@ -121,6 +128,10 @@ return is_bool($value); } + private function eval_type_enum(mixed $value): bool { + return in_array($value, $this->enum); + } + /* ## Public eval methods These are the entry-point eval methods that in turn can call other @@ -152,6 +163,7 @@ Type::BOOLEAN => $match = $this->eval_type_boolean($value, $scope), Type::ARRAY, Type::OBJECT => $match = is_array($value), + Type::ENUM => $match = $this->eval_type_enum($value), Type::NULL => $match = is_null($value) }; diff --git a/src/Ruleset.php b/src/Ruleset.php index d9b9193..cd7eaa9 100644 --- a/src/Ruleset.php +++ b/src/Ruleset.php @@ -84,7 +84,13 @@ // 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}"); + // List allowed enum values + if ($rules->enum) { + $values = implode(" or ", array_map(fn($value): string => "'{$value}'", $rules->enum)); + $this->add_error($name, "Value must be exactly: {$values}"); + } + + $this->add_error($name, "Value must be of type {$types}{$enum_values}"); } if ($rules->min && !$rules->eval_min($value, $scope)) {