From d3e48cc2992ccac3e829df563f87339ca49d9f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Mon, 2 Oct 2023 16:10:39 +0200 Subject: [PATCH] Add Optional::Undefined for optional values --- generator/src/OperatorClassGenerator.php | 3 ++- generator/src/OperatorFactoryGenerator.php | 3 ++- generator/src/OperatorGenerator.php | 6 ++++-- src/Builder/Aggregation.php | 8 ++++---- src/Builder/Aggregation/FilterAggregation.php | 13 +++++++------ src/Builder/BuilderEncoder.php | 3 +-- src/Builder/Optional.php | 13 +++++++++++++ tests/Builder/BuilderCodecTest.php | 8 ++++---- 8 files changed, 37 insertions(+), 20 deletions(-) create mode 100644 src/Builder/Optional.php diff --git a/generator/src/OperatorClassGenerator.php b/generator/src/OperatorClassGenerator.php index e3b153135..2c65d4075 100644 --- a/generator/src/OperatorClassGenerator.php +++ b/generator/src/OperatorClassGenerator.php @@ -6,6 +6,7 @@ use MongoDB\Builder\Stage\StageInterface; use MongoDB\CodeGenerator\Definition\GeneratorDefinition; use MongoDB\CodeGenerator\Definition\OperatorDefinition; +use Nette\PhpGenerator\Literal; use Nette\PhpGenerator\PhpNamespace; use function assert; @@ -75,7 +76,7 @@ public function createClass(GeneratorDefinition $definition, OperatorDefinition PHP); } } elseif ($argument->isOptional) { - $constuctorParam->setDefaultValue(null); + $constuctorParam->setDefaultValue(new Literal('Optional::Undefined')); } $constuctor->addComment('@param ' . $type->doc . ' $' . $argument->name); diff --git a/generator/src/OperatorFactoryGenerator.php b/generator/src/OperatorFactoryGenerator.php index dc2d0bb39..b7e63594c 100644 --- a/generator/src/OperatorFactoryGenerator.php +++ b/generator/src/OperatorFactoryGenerator.php @@ -5,6 +5,7 @@ use MongoDB\CodeGenerator\Definition\GeneratorDefinition; use MongoDB\CodeGenerator\Definition\OperatorDefinition; +use Nette\PhpGenerator\Literal; use Nette\PhpGenerator\PhpNamespace; use function implode; @@ -52,7 +53,7 @@ private function createFactoryClass(GeneratorDefinition $definition): PhpNamespa $args[] = '...$' . $argument->name; } else { if ($argument->isOptional) { - $parameter->setDefaultValue(null); + $parameter->setDefaultValue(new Literal('Optional::Undefined')); } $method->addComment('@param ' . $type->doc . ' $' . $argument->name); diff --git a/generator/src/OperatorGenerator.php b/generator/src/OperatorGenerator.php index 1b5b65dbb..2b272c115 100644 --- a/generator/src/OperatorGenerator.php +++ b/generator/src/OperatorGenerator.php @@ -4,6 +4,7 @@ namespace MongoDB\CodeGenerator; use MongoDB\Builder\Expression\ExpressionInterface; +use MongoDB\Builder\Optional; use MongoDB\CodeGenerator\Definition\ArgumentDefinition; use MongoDB\CodeGenerator\Definition\ExpressionDefinition; use MongoDB\CodeGenerator\Definition\GeneratorDefinition; @@ -112,8 +113,9 @@ final protected function generateExpressionTypes(ArgumentDefinition $arg): objec } if ($arg->isOptional) { - $nativeTypes[] = 'null'; - $docTypes[] = 'null'; + $use[] = '\\' . Optional::class; + $docTypes[] = 'Undefined'; + $nativeTypes[] = Optional::class; } // mixed can only be used as a standalone type diff --git a/src/Builder/Aggregation.php b/src/Builder/Aggregation.php index 357e7c709..5d27daacd 100644 --- a/src/Builder/Aggregation.php +++ b/src/Builder/Aggregation.php @@ -49,14 +49,14 @@ public static function eq(mixed $expression1, mixed $expression2): EqAggregation /** * @param BSONArray|PackedArray|ResolvesToArray|list $input * @param ResolvesToBool|bool $cond - * @param ResolvesToString|non-empty-string|null $as - * @param Int64|ResolvesToInt|int|null $limit + * @param ResolvesToString|Undefined|non-empty-string $as + * @param Int64|ResolvesToInt|Undefined|int $limit */ public static function filter( PackedArray|ResolvesToArray|BSONArray|array $input, ResolvesToBool|bool $cond, - ResolvesToString|null|string $as = null, - Int64|ResolvesToInt|int|null $limit = null, + Optional|ResolvesToString|string $as = Optional::Undefined, + Optional|Int64|ResolvesToInt|int $limit = Optional::Undefined, ): FilterAggregation { return new FilterAggregation($input, $cond, $as, $limit); diff --git a/src/Builder/Aggregation/FilterAggregation.php b/src/Builder/Aggregation/FilterAggregation.php index f48842d20..78476ef9e 100644 --- a/src/Builder/Aggregation/FilterAggregation.php +++ b/src/Builder/Aggregation/FilterAggregation.php @@ -13,6 +13,7 @@ use MongoDB\Builder\Expression\ResolvesToBool; use MongoDB\Builder\Expression\ResolvesToInt; use MongoDB\Builder\Expression\ResolvesToString; +use MongoDB\Builder\Optional; use MongoDB\Model\BSONArray; class FilterAggregation implements ResolvesToArray @@ -22,20 +23,20 @@ class FilterAggregation implements ResolvesToArray public PackedArray|ResolvesToArray|BSONArray|array $input; public ResolvesToBool|bool $cond; - public ResolvesToString|null|string $as; - public Int64|ResolvesToInt|int|null $limit; + public Optional|ResolvesToString|string $as; + public Optional|Int64|ResolvesToInt|int $limit; /** * @param BSONArray|PackedArray|ResolvesToArray|list $input * @param ResolvesToBool|bool $cond - * @param ResolvesToString|non-empty-string|null $as - * @param Int64|ResolvesToInt|int|null $limit + * @param ResolvesToString|Undefined|non-empty-string $as + * @param Int64|ResolvesToInt|Undefined|int $limit */ public function __construct( PackedArray|ResolvesToArray|BSONArray|array $input, ResolvesToBool|bool $cond, - ResolvesToString|null|string $as = null, - Int64|ResolvesToInt|int|null $limit = null, + Optional|ResolvesToString|string $as = Optional::Undefined, + Optional|Int64|ResolvesToInt|int $limit = Optional::Undefined, ) { if (\is_array($input) && ! \array_is_list($input)) { throw new \InvalidArgumentException('Expected $input argument to be a list, got an associative array.'); diff --git a/src/Builder/BuilderEncoder.php b/src/Builder/BuilderEncoder.php index f58ea30d9..df3b46d28 100644 --- a/src/Builder/BuilderEncoder.php +++ b/src/Builder/BuilderEncoder.php @@ -141,8 +141,7 @@ private function encodeAsObject(ExpressionInterface|StageInterface $value): stdC foreach (get_object_vars($value) as $key => $val) { /** @var mixed $val */ $val = $this->encodeIfSupported($val); - // @todo check for undefined value vs null - if ($val !== null) { + if ($val !== Optional::Undefined) { $result->{$key} = $val; } } diff --git a/src/Builder/Optional.php b/src/Builder/Optional.php new file mode 100644 index 000000000..d2a430d97 --- /dev/null +++ b/src/Builder/Optional.php @@ -0,0 +1,13 @@ + [ - null, + [], [], ]; yield 'int limit' => [ - 1, + [1], ['limit' => 1], ]; }