浏览代码

added support for Rule::enum

Missael H. Anda 2 年之前
父节点
当前提交
e22833fc1a
共有 2 个文件被更改,包括 41 次插入20 次删除
  1. 39 18
      src/Extracting/Strategies/GetFromInlineValidatorBase.php
  2. 2 2
      tests/Fixtures/TestController.php

+ 39 - 18
src/Extracting/Strategies/GetFromInlineValidatorBase.php

@@ -85,25 +85,10 @@ class GetFromInlineValidatorBase extends Strategy
                     // Try to extract Enum rule
                     else if (
                         function_exists('enum_exists') &&
-                        $arrayItem->value instanceof Node\Expr\New_ &&
-                        $arrayItem->value->class instanceof Node\Name &&
-                        last($arrayItem->value->class->parts) === 'Enum' &&
-                        count($arrayItem->value->args) === 1 &&
-                        ($arg = $arrayItem->value->args[0]) instanceof Node\Arg
+                        ($enum = $this->extractEnumClassFromArrayItem($arrayItem)) &&
+                        enum_exists($enum) && method_exists($enum, 'tryFrom')
                     ) {
-                        $enum = null;
-
-                        if ($arg->value instanceof Node\Expr\ClassConstFetch &&
-                            $arg->value->class instanceof Node\Name
-                        ) {
-                            $enum = '\\' . implode('\\', $arg->value->class->parts);
-                        } else if ($arg->value instanceof Node\Scalar\String_) {
-                            $enum = $arg->value->value;
-                        }
-
-                        if ($enum !== null && enum_exists($enum) && method_exists($enum, 'tryFrom')) {
-                            $rulesList[] = 'in:' . implode(',', array_map(fn ($case) => $case->value, $enum::cases()));
-                        }
+                        $rulesList[] = 'in:' . implode(',', array_map(fn ($case) => $case->value, $enum::cases()));
                     }
                 }
                 $rules[$paramName] = join('|', $rulesList);
@@ -134,6 +119,42 @@ class GetFromInlineValidatorBase extends Strategy
         return [$rules, $customParameterData];
     }
 
+    protected function extractEnumClassFromArrayItem(Node\Expr\ArrayItem $arrayItem): ?string
+    {
+        $args = [];
+
+        // Enum rule with the form "new Enum(...)"
+        if ($arrayItem->value instanceof Node\Expr\New_ &&
+            $arrayItem->value->class instanceof Node\Name &&
+            last($arrayItem->value->class->parts) === 'Enum'
+        ) {
+            $args = $arrayItem->value->args;
+        }
+
+        // Enum rule with the form "Rule::enum(...)"
+        else if ($arrayItem->value instanceof Node\Expr\StaticCall &&
+            $arrayItem->value->class instanceof Node\Name &&
+            last($arrayItem->value->class->parts) === 'Rule' &&
+            $arrayItem->value->name instanceof Node\Identifier &&
+            $arrayItem->value->name->name === 'enum'
+        ) {
+            $args = $arrayItem->value->args;
+        }
+
+        if (count($args) !== 1 || !$args[0] instanceof Node\Arg) return null;
+
+        $arg = $args[0];
+        if ($arg->value instanceof Node\Expr\ClassConstFetch &&
+            $arg->value->class instanceof Node\Name
+        ) {
+            return '\\' . implode('\\', $arg->value->class->parts);
+        } else if ($arg->value instanceof Node\Scalar\String_) {
+            return $arg->value->value;
+        }
+
+        return null;
+    }
+
     protected function getMissingCustomDataMessage($parameterName)
     {
         return "No extra data found for parameter '$parameterName' from your inline validator. You can add a comment above '$parameterName' with a description and example.";

+ 2 - 2
tests/Fixtures/TestController.php

@@ -4,7 +4,7 @@ namespace Knuckles\Scribe\Tests\Fixtures;
 
 use Illuminate\Http\Request;
 use Illuminate\Routing\Controller;
-use Illuminate\Validation\Rules;
+use Illuminate\Validation\Rule;
 use Knuckles\Scribe\Tools\Utils;
 
 /**
@@ -583,7 +583,7 @@ class TestController extends Controller
     {
         $request->validate([
             'enum_class' => ['required', new Rules\Enum(\Knuckles\Scribe\Tests\Fixtures\TestStringBackedEnum::class), 'nullable'],
-            'enum_string' => ['required', new Rules\Enum('\Knuckles\Scribe\Tests\Fixtures\TestIntegerBackedEnum'), 'nullable'],
+            'enum_string' => ['required', Rule::enum('\Knuckles\Scribe\Tests\Fixtures\TestIntegerBackedEnum'), 'nullable'],
             // Not full path class call won't work
             'enum_inexistent' => ['required', new Rules\Enum(TestStringBackedEnum::class)],
         ]);