diff --git a/src/Contract/ParserInterface.php b/src/Contract/ParserInterface.php index 83a950e..b75f31d 100644 --- a/src/Contract/ParserInterface.php +++ b/src/Contract/ParserInterface.php @@ -197,6 +197,15 @@ public function getArgDefine($nameOrIndex): array; */ public function getArg($nameOrIndex, $default = null); + /** + * Get an argument value by name, will throw exception on not input + * + * @param string|int $nameOrIndex + * + * @return mixed + */ + public function getMustArg($nameOrIndex, string $errMsg = ''); + /** * Set trusted argument value, will not format and validate value. * diff --git a/src/Flags.php b/src/Flags.php index 86dedfe..1a7dfb4 100644 --- a/src/Flags.php +++ b/src/Flags.php @@ -9,6 +9,7 @@ namespace Toolkit\PFlag; +use InvalidArgumentException; use RuntimeException; use Toolkit\PFlag\Contract\ParserInterface; use Toolkit\PFlag\Exception\FlagException; @@ -589,11 +590,7 @@ public function hasArg($nameOrIndex): bool */ public function setArg($nameOrIndex, $value): void { - $arg = $this->getArgument($nameOrIndex); - if (!$arg) { // not exist - throw new FlagException("flag argument '$nameOrIndex' is undefined"); - } - + $arg = $this->mustGetArgument($nameOrIndex); $arg->setValue($value); } @@ -603,14 +600,31 @@ public function setArg($nameOrIndex, $value): void */ public function setTrustedArg(string $name, $value): void { - $arg = $this->getArgument($name); - if (!$arg) { // not exist - throw new FlagException("flag argument '$name' is undefined"); - } + $arg = $this->mustGetArgument($name); $arg->setTrustedValue($value); } + /** + * @param string|int $nameOrIndex + * + * @return mixed + */ + public function getMustArg($nameOrIndex, string $errMsg = '') + { + $arg = $this->mustGetArgument($nameOrIndex); + if ($arg->hasValue()) { + return $arg->getValue(); + } + + if (!$errMsg) { + $errName = $arg->getNameMark(); + $errMsg = "The argument '$errName' is required"; + } + + throw new InvalidArgumentException($errMsg); + } + /** * @param string|int $nameOrIndex * @param null|mixed $default @@ -619,10 +633,7 @@ public function setTrustedArg(string $name, $value): void */ public function getArg($nameOrIndex, $default = null) { - $arg = $this->getArgument($nameOrIndex); - if (!$arg) { // not exist - throw new FlagException("flag argument '$nameOrIndex' is undefined"); - } + $arg = $this->mustGetArgument($nameOrIndex); if ($arg->hasValue()) { return $arg->getValue(); @@ -631,6 +642,21 @@ public function getArg($nameOrIndex, $default = null) return $default ?? $arg->getTypeDefault(); } + /** + * @param string|int $nameOrIndex + * + * @return Argument + */ + protected function mustGetArgument($nameOrIndex): Argument + { + $arg = $this->getArgument($nameOrIndex); + if (!$arg) { // not exist + throw new FlagException("flag argument '$nameOrIndex' is undefined"); + } + + return $arg; + } + /** * @param string|int $nameOrIndex * diff --git a/src/SFlags.php b/src/SFlags.php index a819f58..642644c 100644 --- a/src/SFlags.php +++ b/src/SFlags.php @@ -96,7 +96,7 @@ class SFlags extends FlagsParser private $name2index = []; /** - * Parsed argument values + * Parsed input argument values * - key is a self-increasing index * * ```php @@ -895,12 +895,9 @@ public function getArgument($nameOrIndex, $default = null) */ public function setArg($nameOrIndex, $value): void { - $index = $this->getArgIndex($nameOrIndex); - if ($index < 0) { - throw new FlagException("flag argument '$nameOrIndex' is undefined"); - } - + $index = $this->mustGetArgIndex($nameOrIndex); $define = $this->argDefines[$index]; + // set value $this->args[$index] = FlagType::fmtBasicTypeValue($define['type'], $value); } @@ -911,10 +908,7 @@ public function setArg($nameOrIndex, $value): void */ public function setTrustedArg(string $name, $value): void { - $index = $this->getArgIndex($name); - if ($index < 0) { - throw new FlagException("flag argument '$name' is undefined"); - } + $index = $this->mustGetArgIndex($name); $this->args[$index] = $value; } @@ -927,10 +921,7 @@ public function setTrustedArg(string $name, $value): void */ public function getArg($nameOrIndex, $default = null) { - $index = $this->getArgIndex($nameOrIndex); - if ($index < 0) { - throw new FlagException("flag argument '$nameOrIndex' is undefined"); - } + $index = $this->mustGetArgIndex($nameOrIndex); if (isset($this->args[$index])) { return $this->args[$index]; @@ -941,6 +932,42 @@ public function getArg($nameOrIndex, $default = null) return $default ?? FlagType::getDefault($define['type']); } + /** + * @param string|int $nameOrIndex + * + * @return mixed + */ + public function getMustArg($nameOrIndex, string $errMsg = '') + { + $index = $this->mustGetArgIndex($nameOrIndex); + if (isset($this->args[$index])) { + return $this->args[$index]; + } + + if (!$errMsg) { + $define = $this->argDefines[$index]; + $errName = $define['name'] ? "#$index({$define['name']})" : "#$index"; + $errMsg = "The argument '$errName' is required"; + } + + throw new InvalidArgumentException($errMsg); + } + + /** + * @param string|int $nameOrIndex + * + * @return int + */ + protected function mustGetArgIndex($nameOrIndex): int + { + $index = $this->getArgIndex($nameOrIndex); + if ($index < 0) { + throw new FlagException("flag argument '$nameOrIndex' is undefined"); + } + + return $index; + } + /** * @param string|int $nameOrIndex * diff --git a/test/FlagsParserTest.php b/test/FlagsParserTest.php index a83198f..3923785 100644 --- a/test/FlagsParserTest.php +++ b/test/FlagsParserTest.php @@ -2,6 +2,7 @@ namespace Toolkit\PFlagTest; +use InvalidArgumentException; use Toolkit\PFlag\Exception\FlagException; use Toolkit\PFlag\FlagsParser; use function get_class; @@ -68,7 +69,16 @@ private function doTestGetOptAndGetArg(FlagsParser $fs): void $this->assertTrue($ok); $this->assertSame(335, $fs->getOpt('int-opt')); $this->assertSame(233, $fs->getArg('int-arg')); + $this->assertSame(233, $fs->getMustArg('int-arg')); $fs->resetResults(); + + // getMustArg + $e = $this->runAndGetException(function (FlagsParser $fs) { + $fs->getMustArg('str-arg'); + }, $fs); + + $this->assertSame(InvalidArgumentException::class, get_class($e)); + $this->assertSame("The argument '#1(str-arg)' is required", $e->getMessage()); } public function testParse_specialArg(): void