From 6684067b9efd41d81f3cf048576a70af1b947c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20=C5=A0tancl?= Date: Fri, 12 Jan 2024 23:11:09 +0100 Subject: [PATCH] Add stringOptions() method to the Options trait (resolve #12) --- src/Options.php | 32 +++++++++++++++++++++++++++++++- tests/Pest/OptionsTest.php | 16 ++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/Options.php b/src/Options.php index 3e55328..46dee50 100644 --- a/src/Options.php +++ b/src/Options.php @@ -5,10 +5,11 @@ declare(strict_types=1); namespace ArchTech\Enums; use BackedEnum; +use Closure; trait Options { - /** Get an associative array of [case name => case value]. */ + /** Get an associative array of [case name => case value] or an indexed array [case name, case name] in the case of pure enums. */ public static function options(): array { $cases = static::cases(); @@ -17,4 +18,33 @@ trait Options ? array_column($cases, 'value', 'name') : array_column($cases, 'name'); } + + /** + * Generate a string format of the enum options using the provided callback and glue. + * @param Closure(string $name, mixed $value): string $callback + */ + public static function stringOptions(Closure $callback = null, string $glue = '\n'): string + { + $firstCase = static::cases()[0] ?? null; + + if ($firstCase === null) { + return ''; + } elseif ($firstCase instanceof BackedEnum) { + // [name => value] + $options = static::options(); + } else { + // [name, name] + $options = static::options(); + + // [name => name, name => name] + $options = array_combine($options, $options); + } + + // Default callback + $callback ??= fn ($name, $value) => "'; + + $options = array_map($callback, array_keys($options), array_values($options)); + + return implode($glue, $options); + } } diff --git a/tests/Pest/OptionsTest.php b/tests/Pest/OptionsTest.php index b581223..477158a 100644 --- a/tests/Pest/OptionsTest.php +++ b/tests/Pest/OptionsTest.php @@ -11,3 +11,19 @@ it('can return an indexed array of options from a pure enum') 0 => 'ADMIN', 1 => 'GUEST', ]); + +it('can return a string of options from a backed enum') + ->expect(Status::stringOptions(fn ($name, $value) => "$name => $value", ', ')) + ->toBe("PENDING => 0, DONE => 1"); + +it('can return a string of options from a pure enum') + ->expect(Role::stringOptions(fn ($name, $value) => "$name => $value", ', ')) + ->toBe("ADMIN => ADMIN, GUEST => GUEST"); + +it('returns default HTML options from backed enums') + ->expect(Status::stringOptions()) + ->toBe('\n'); + +it('returns default HTML options from pure enums') + ->expect(Role::stringOptions()) + ->toBe('\n');