1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | namespace Cerbero\LaravelEnum; |
||
6 | |||
7 | use Generator; |
||
8 | |||
9 | /** |
||
10 | * Determine whether the given namespace exists. |
||
11 | */ |
||
12 | function namespaceExists(string $target): bool |
||
13 | { |
||
14 | return class_exists($target) || interface_exists($target); |
||
15 | } |
||
16 | |||
17 | /** |
||
18 | * Yield the content of the given path line by line. |
||
19 | * |
||
20 | * @return Generator<int, string> |
||
21 | */ |
||
22 | function yieldLines(string $path): Generator |
||
23 | { |
||
24 | $stream = fopen($path, 'rb'); |
||
25 | |||
26 | try { |
||
27 | while (($line = fgets($stream, 1024)) !== false) { |
||
28 | yield $line; |
||
29 | } |
||
30 | } finally { |
||
31 | is_resource($stream) && fclose($stream); |
||
32 | } |
||
33 | } |
||
34 | |||
35 | /** |
||
36 | * Retrieve the common type among the given types. |
||
37 | */ |
||
38 | function commonType(string ...$types): string |
||
39 | { |
||
40 | $null = ''; |
||
41 | $types = array_unique($types); |
||
42 | |||
43 | if (($index = array_search('null', $types)) !== false) { |
||
44 | $null = '?'; |
||
45 | |||
46 | unset($types[$index]); |
||
47 | } |
||
48 | |||
49 | return match (true) { |
||
50 | ! is_null($common = commonInterfaceOrParent(...$types)) => $null . $common, |
||
51 | count($types) == 1 => $null . reset($types), |
||
52 | default => implode('|', $types) . ($null ? '|null' : ''), |
||
53 | }; |
||
54 | } |
||
55 | |||
56 | /** |
||
57 | * Retrieve the first interface or parent class in common with the given classes. |
||
58 | * |
||
59 | * @return ?class-string |
||
0 ignored issues
–
show
Documentation
Bug
introduced
by
![]() |
|||
60 | */ |
||
61 | function commonInterfaceOrParent(string ...$classes): ?string |
||
62 | { |
||
63 | if ($classes !== array_filter($classes, namespaceExists(...))) { |
||
64 | return null; |
||
65 | } |
||
66 | |||
67 | foreach (['class_implements', 'class_parents'] as $callback) { |
||
68 | /** @var array<class-string, class-string> $common */ |
||
69 | if ($common = array_intersect(...array_map($callback, $classes))) { |
||
70 | return reset($common); |
||
71 | } |
||
72 | } |
||
73 | |||
74 | return null; |
||
75 | } |
||
76 |