From be1e2f7fbcfa6980c0187bda8e17407b4385b3bd Mon Sep 17 00:00:00 2001 From: Kevin Bond Date: Sat, 9 Jan 2021 11:55:19 -0500 Subject: [PATCH] [feature] allow invoke parameters to be optional --- src/Callback.php | 8 +++++++- src/Callback/Parameter.php | 20 ++++++++++++++++++++ tests/CallbackTest.php | 12 ++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/Callback.php b/src/Callback.php index 5e4717b..0e05f9a 100644 --- a/src/Callback.php +++ b/src/Callback.php @@ -53,10 +53,16 @@ public function invoke(...$arguments) continue; } - if (!\array_key_exists($key, $parameters)) { + if (!\array_key_exists($key, $parameters) && !$argument->isOptional()) { throw new \ArgumentCountError(\sprintf('No argument %d for callable. Expected type: "%s".', $key + 1, $argument->type())); } + if ($argument->isOptional()) { + $arguments[$key] = null; + + continue; + } + try { $arguments[$key] = $argument->resolve($parameters[$key]); } catch (UnresolveableArgument $e) { diff --git a/src/Callback/Parameter.php b/src/Callback/Parameter.php index ff85e90..3113afb 100644 --- a/src/Callback/Parameter.php +++ b/src/Callback/Parameter.php @@ -12,6 +12,9 @@ */ abstract class Parameter { + /** @var bool */ + private $optional = false; + final public static function union(self ...$parameters): self { return new UnionParameter(...$parameters); @@ -32,7 +35,16 @@ final public static function factory(callable $factory): ValueFactory return new ValueFactory($factory); } + final public function optional(): self + { + $this->optional = true; + + return $this; + } + /** + * @internal + * * @return mixed * * @throws UnresolveableArgument @@ -54,6 +66,14 @@ final public function resolve(\ReflectionParameter $parameter) return $value($type->getName()); } + /** + * @internal + */ + final public function isOptional(): bool + { + return $this->optional; + } + abstract public function type(): string; abstract protected function valueFor(\ReflectionParameter $refParameter); diff --git a/tests/CallbackTest.php b/tests/CallbackTest.php index 9680003..2f50f42 100644 --- a/tests/CallbackTest.php +++ b/tests/CallbackTest.php @@ -261,6 +261,18 @@ public function invoke_with_not_enough_required_arguments(): void ) ; } + + /** + * @test + */ + public function can_mark_invoke_parameter_arguments_as_optional(): void + { + $actual = Callback::createFor(static function() { return 'ret'; }) + ->invoke(Parameter::typed('string', 'foobar')->optional()) + ; + + $this->assertSame('ret', $actual); + } } class Object1