diff --git a/src/CommandLine/Parser.php b/src/CommandLine/Parser.php
index 0c75125..33805bc 100644
--- a/src/CommandLine/Parser.php
+++ b/src/CommandLine/Parser.php
@@ -21,6 +21,7 @@ class Parser
Repeatable = 'repeatable',
Enum = 'enum',
RealPath = 'realpath',
+ Normalizer = 'normalizer',
Default = 'default';
/** @deprecated use Parser::Argument */
@@ -139,9 +140,11 @@ public function parse(?array $args = null): array
}
}
+ $this->checkArg($opt, $arg);
+
if (
!empty($opt[self::Enum])
- && !in_array($arg, $opt[self::Enum], true)
+ && !in_array(is_array($arg) ? reset($arg) : $arg, $opt[self::Enum], true)
&& !(
$opt[self::Optional]
&& $arg === true
@@ -150,8 +153,6 @@ public function parse(?array $args = null): array
throw new \Exception("Value of option $name must be " . implode(', or ', $opt[self::Enum]) . '.');
}
- $this->checkArg($opt, $arg);
-
if (empty($opt[self::Repeatable])) {
$params[$name] = $arg;
} else {
@@ -187,6 +188,10 @@ public function help(): void
public function checkArg(array $opt, &$arg): void
{
+ if (isset($opt[self::Normalizer])) {
+ $arg = $opt[self::Normalizer]($arg);
+ }
+
if (!empty($opt[self::RealPath])) {
$path = realpath($arg);
if ($path === false) {
diff --git a/tests/Parser.phpt b/tests/Parser.phpt
index 4031106..cb6a729 100644
--- a/tests/Parser.phpt
+++ b/tests/Parser.phpt
@@ -194,6 +194,36 @@ test('realpath', function () {
+test('normalizer', function () {
+ $cmd = new Parser('
+ -p param
+ ', [
+ '-p' => [Parser::Normalizer => function ($arg) { return "$arg-normalized"; }],
+ ]);
+
+ Assert::same(['-p' => 'val-normalized'], $cmd->parse(explode(' ', '-p val')));
+
+
+ $cmd = new Parser('
+ -p
+ ', [
+ '-p' => [Parser::Normalizer => function () { return 'a'; }],
+ ]);
+
+ Assert::same(['-p' => 'a'], $cmd->parse(explode(' ', '-p xxx')));
+
+
+ $cmd = new Parser('
+ -p
+ ', [
+ '-p' => [Parser::Normalizer => function () { return ['a', 'foo']; }],
+ ]);
+
+ Assert::same(['-p' => ['a', 'foo']], $cmd->parse(explode(' ', '-p xxx')));
+});
+
+
+
test('positional arguments', function () {
$cmd = new Parser('', [
'pos' => [],