From 3a745a52d0804968dc054384382960037fef1315 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 24 Jul 2022 17:36:04 +0200 Subject: [PATCH 01/39] change email --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 31208c5..cfc9ea6 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ "authors": [ { "name": "Baptiste Langlade", - "email": "langlade.baptiste@gmail.com" + "email": "baptiste.langlade@hey.com" } ], "support": { From 4457915b10c96bd2050a0f0a73661b952bcea5d9 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 24 Jul 2022 17:37:04 +0200 Subject: [PATCH 02/39] use ramsey/composer-install --- .github/workflows/ci.yml | 39 ++++++--------------------------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85ef7d9..e996b66 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,17 +19,8 @@ jobs: php-version: ${{ matrix.php-version }} extensions: mbstring, intl coverage: xdebug - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - name: Install Dependencies - run: composer install + - name: Composer + uses: "ramsey/composer-install@v2" - name: PHPUnit run: vendor/bin/phpunit --coverage-clover=coverage.clover - uses: codecov/codecov-action@v1 @@ -49,17 +40,8 @@ jobs: with: php-version: ${{ matrix.php-version }} extensions: mbstring, intl - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-composer- - - name: Install Dependencies - run: composer install + - name: Composer + uses: "ramsey/composer-install@v2" - name: Psalm run: vendor/bin/psalm --shepherd cs: @@ -76,16 +58,7 @@ jobs: with: php-version: ${{ matrix.php-version }} extensions: mbstring, intl - - name: Get Composer Cache Directory - id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-${{ matrix.php-version }}-composer-${{ hashFiles('**/composer.json') }} - restore-keys: ${{ runner.os }}-${{ matrix.php-version }}-composer- - - name: Install Dependencies - run: composer install --no-progress + - name: Composer + uses: "ramsey/composer-install@v2" - name: CS run: vendor/bin/php-cs-fixer fix --diff --dry-run --diff-format udiff From 666813782c659adfdae3fc60e523211a565fcd2f Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 24 Jul 2022 17:40:11 +0200 Subject: [PATCH 03/39] require php 8.1 --- .github/workflows/ci.yml | 6 +++--- composer.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e996b66..24a37d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macOS-latest] - php-version: ['7.4', '8.0'] + php-version: ['8.1'] name: 'PHPUnit' steps: - name: Checkout @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: ['7.4', '8.0'] + php-version: ['8.1'] name: 'Psalm' steps: - name: Checkout @@ -48,7 +48,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: ['7.4'] + php-version: ['8.1'] name: 'CS' steps: - name: Checkout diff --git a/composer.json b/composer.json index cfc9ea6..8e01b7b 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "issues": "http://github.com/Innmind/UrlTemplate/issues" }, "require": { - "php": "~7.4|~8.0", + "php": "~8.1", "innmind/url": "~3.0", "innmind/immutable": "~3.1" }, From 833abea9370a9ea34328f2e23d7f59e9ba2a0e64 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 24 Jul 2022 17:42:19 +0200 Subject: [PATCH 04/39] use CS 2 --- .github/workflows/ci.yml | 2 +- .php_cs.dist => .php-cs-fixer.dist.php | 0 composer.json | 2 +- src/Expression/Level4/Composite.php | 6 +-- src/Template.php | 4 +- tests/Expression/Level1Test.php | 14 +++---- tests/Expression/Level2/FragmentTest.php | 16 ++++---- tests/Expression/Level2/ReservedTest.php | 16 ++++---- tests/Expression/Level3/FragmentTest.php | 10 ++--- tests/Expression/Level3/LabelTest.php | 10 ++--- tests/Expression/Level3/ParametersTest.php | 10 ++--- tests/Expression/Level3/PathTest.php | 10 ++--- .../Level3/QueryContinuationTest.php | 10 ++--- tests/Expression/Level3/QueryTest.php | 10 ++--- tests/Expression/Level3/ReservedTest.php | 10 ++--- tests/Expression/Level3Test.php | 10 ++--- tests/Expression/Level4/CompositeTest.php | 38 +++++++++---------- tests/Expression/Level4/FragmentTest.php | 26 ++++++------- tests/Expression/Level4/LabelTest.php | 26 ++++++------- tests/Expression/Level4/ParametersTest.php | 26 ++++++------- tests/Expression/Level4/PathTest.php | 24 ++++++------ .../Level4/QueryContinuationTest.php | 26 ++++++------- tests/Expression/Level4/QueryTest.php | 26 ++++++------- tests/Expression/Level4/ReservedTest.php | 26 ++++++------- tests/Expression/Level4Test.php | 30 +++++++-------- tests/ExpressionsTest.php | 2 +- tests/UrlEncodeTest.php | 4 +- 27 files changed, 197 insertions(+), 197 deletions(-) rename .php_cs.dist => .php-cs-fixer.dist.php (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24a37d4..1ef3b2d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -61,4 +61,4 @@ jobs: - name: Composer uses: "ramsey/composer-install@v2" - name: CS - run: vendor/bin/php-cs-fixer fix --diff --dry-run --diff-format udiff + run: vendor/bin/php-cs-fixer fix --diff --dry-run diff --git a/.php_cs.dist b/.php-cs-fixer.dist.php similarity index 100% rename from .php_cs.dist rename to .php-cs-fixer.dist.php diff --git a/composer.json b/composer.json index 8e01b7b..851fdb9 100644 --- a/composer.json +++ b/composer.json @@ -33,6 +33,6 @@ "phpunit/phpunit": "~9.0", "vimeo/psalm": "~4.4", "innmind/black-box": "^4.16", - "innmind/coding-standard": "^1.1" + "innmind/coding-standard": "~2.0" } } diff --git a/src/Expression/Level4/Composite.php b/src/Expression/Level4/Composite.php index 9e7a277..f8349f4 100644 --- a/src/Expression/Level4/Composite.php +++ b/src/Expression/Level4/Composite.php @@ -29,7 +29,7 @@ final class Composite implements Expression public function __construct( string $separator, Expression $level4, - Expression ...$expressions + Expression ...$expressions, ) { $this->separator = $separator; $this->type = \get_class($level4); @@ -40,7 +40,7 @@ public function __construct( public static function removeLead( string $separator, Expression $level4, - Expression ...$expressions + Expression ...$expressions, ): self { $self = new self($separator, $level4, ...$expressions); $self->removeLead = true; @@ -127,7 +127,7 @@ function(Expression $expression): string { 'string', static fn($expression) => $expression->regex(), ) - ->append($remaining) + ->append($remaining), )->toString(); } diff --git a/src/Template.php b/src/Template.php index 7e41fd0..105cadf 100644 --- a/src/Template.php +++ b/src/Template.php @@ -55,7 +55,7 @@ static function(Str $template, Expression $expression) use ($variables): Str { $expression->toString(), $expression->expand($variables), ); - } + }, ); return Url::of($url->toString()); @@ -112,7 +112,7 @@ public function toString(): string */ private function extractExpressions( Sequence $expressions, - Str $template + Str $template, ): Sequence { $captured = $template->capture('~(\{[\+#\./;\?&]?[a-zA-Z0-9_]+(\*|:\d+)?(,[a-zA-Z0-9_]+(\*|:\d+)?)*\})~'); diff --git a/tests/Expression/Level1Test.php b/tests/Expression/Level1Test.php index 772d639..f86215e 100644 --- a/tests/Expression/Level1Test.php +++ b/tests/Expression/Level1Test.php @@ -22,7 +22,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Level1(new Name('foo')) + new Level1(new Name('foo')), ); } @@ -36,13 +36,13 @@ public function testExpand() $expression = new Level1(new Name('foo')); $this->assertSame('value', $expression->expand( - Map::of('string', 'variable')('foo', 'value') + Map::of('string', 'variable')('foo', 'value'), )); $this->assertSame('Hello%20World%21', $expression->expand( - Map::of('string', 'variable')('foo', 'Hello World!') + Map::of('string', 'variable')('foo', 'Hello World!'), )); $this->assertSame('', $expression->expand( - Map::of('string', 'variable') + Map::of('string', 'variable'), )); } @@ -50,7 +50,7 @@ public function testOf() { $this->assertInstanceOf( Level1::class, - $expression = Level1::of(Str::of('{foo}')) + $expression = Level1::of(Str::of('{foo}')), ); $this->assertSame('{foo}', $expression->toString()); } @@ -67,7 +67,7 @@ public function testRegex() { $this->assertSame( '(?[a-zA-Z0-9\%\-\.\_\~]*)', - Level1::of(Str::of('{foo}'))->regex() + Level1::of(Str::of('{foo}'))->regex(), ); } @@ -79,7 +79,7 @@ public function testThrowWhenTryingToExpandWithAnArray() $this->expectExceptionMessage('foo'); $expression->expand( - Map::of('string', 'variable')('foo', ['value']) + Map::of('string', 'variable')('foo', ['value']), ); } } diff --git a/tests/Expression/Level2/FragmentTest.php b/tests/Expression/Level2/FragmentTest.php index 4dd427b..6407c41 100644 --- a/tests/Expression/Level2/FragmentTest.php +++ b/tests/Expression/Level2/FragmentTest.php @@ -22,7 +22,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Fragment(new Name('foo')) + new Fragment(new Name('foo')), ); } @@ -36,16 +36,16 @@ public function testExpand() $expression = new Fragment(new Name('foo')); $this->assertSame('#value', $expression->expand( - Map::of('string', 'variable')('foo', 'value') + Map::of('string', 'variable')('foo', 'value'), )); $this->assertSame('#Hello%20World!', $expression->expand( - Map::of('string', 'variable')('foo', 'Hello World!') + Map::of('string', 'variable')('foo', 'Hello World!'), )); $this->assertSame('#/foo/bar', $expression->expand( - Map::of('string', 'variable')('foo', '/foo/bar') + Map::of('string', 'variable')('foo', '/foo/bar'), )); $this->assertSame('', $expression->expand( - Map::of('string', 'variable') + Map::of('string', 'variable'), )); } @@ -53,7 +53,7 @@ public function testOf() { $this->assertInstanceOf( Fragment::class, - $expression = Fragment::of(Str::of('{#foo}')) + $expression = Fragment::of(Str::of('{#foo}')), ); $this->assertSame('{#foo}', $expression->toString()); } @@ -70,7 +70,7 @@ public function testRegex() { $this->assertSame( '\#(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)', - Fragment::of(Str::of('{#foo}'))->regex() + Fragment::of(Str::of('{#foo}'))->regex(), ); } @@ -82,7 +82,7 @@ public function testThrowWhenTryingToExpandWithAnArray() $this->expectExceptionMessage('foo'); $expression->expand( - Map::of('string', 'variable')('foo', ['value']) + Map::of('string', 'variable')('foo', ['value']), ); } } diff --git a/tests/Expression/Level2/ReservedTest.php b/tests/Expression/Level2/ReservedTest.php index 2adaae5..a3bccd9 100644 --- a/tests/Expression/Level2/ReservedTest.php +++ b/tests/Expression/Level2/ReservedTest.php @@ -22,7 +22,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Reserved(new Name('foo')) + new Reserved(new Name('foo')), ); } @@ -36,16 +36,16 @@ public function testExpand() $expression = new Reserved(new Name('foo')); $this->assertSame('value', $expression->expand( - Map::of('string', 'variable')('foo', 'value') + Map::of('string', 'variable')('foo', 'value'), )); $this->assertSame('Hello%20World!', $expression->expand( - Map::of('string', 'variable')('foo', 'Hello World!') + Map::of('string', 'variable')('foo', 'Hello World!'), )); $this->assertSame('/foo/bar', $expression->expand( - Map::of('string', 'variable')('foo', '/foo/bar') + Map::of('string', 'variable')('foo', '/foo/bar'), )); $this->assertSame('', $expression->expand( - Map::of('string', 'variable') + Map::of('string', 'variable'), )); } @@ -53,7 +53,7 @@ public function testOf() { $this->assertInstanceOf( Reserved::class, - $expression = Reserved::of(Str::of('{+foo}')) + $expression = Reserved::of(Str::of('{+foo}')), ); $this->assertSame('{+foo}', $expression->toString()); } @@ -70,7 +70,7 @@ public function testRegex() { $this->assertSame( '(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)', - Reserved::of(Str::of('{+foo}'))->regex() + Reserved::of(Str::of('{+foo}'))->regex(), ); } @@ -82,7 +82,7 @@ public function testThrowWhenTryingToExpandWithAnArray() $this->expectExceptionMessage('foo'); $expression->expand( - Map::of('string', 'variable')('foo', ['value']) + Map::of('string', 'variable')('foo', ['value']), ); } } diff --git a/tests/Expression/Level3/FragmentTest.php b/tests/Expression/Level3/FragmentTest.php index 91a1a94..3b0fd2c 100644 --- a/tests/Expression/Level3/FragmentTest.php +++ b/tests/Expression/Level3/FragmentTest.php @@ -21,7 +21,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Fragment(new Name('foo'), new Name('bar')) + new Fragment(new Name('foo'), new Name('bar')), ); } @@ -45,11 +45,11 @@ public function testExpand() $this->assertSame( '#1024,Hello%20World!,768', - (new Fragment(new Name('x'), new Name('hello'), new Name('y')))->expand($variables) + (new Fragment(new Name('x'), new Name('hello'), new Name('y')))->expand($variables), ); $this->assertSame( '#/foo/bar,1024', - (new Fragment(new Name('path'), new Name('x')))->expand($variables) + (new Fragment(new Name('path'), new Name('x')))->expand($variables), ); } @@ -57,7 +57,7 @@ public function testOf() { $this->assertInstanceOf( Fragment::class, - $expression = Fragment::of(Str::of('{#foo,bar}')) + $expression = Fragment::of(Str::of('{#foo,bar}')), ); $this->assertSame('{#foo,bar}', $expression->toString()); } @@ -74,7 +74,7 @@ public function testRegex() { $this->assertSame( '\#(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*),(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)', - Fragment::of(Str::of('{#foo,bar}'))->regex() + Fragment::of(Str::of('{#foo,bar}'))->regex(), ); } } diff --git a/tests/Expression/Level3/LabelTest.php b/tests/Expression/Level3/LabelTest.php index ad1b4f1..465dac8 100644 --- a/tests/Expression/Level3/LabelTest.php +++ b/tests/Expression/Level3/LabelTest.php @@ -21,7 +21,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Label(new Name('foo'), new Name('bar')) + new Label(new Name('foo'), new Name('bar')), ); } @@ -45,11 +45,11 @@ public function testExpand() $this->assertSame( '.1024.768', - (new Label(new Name('x'), new Name('y')))->expand($variables) + (new Label(new Name('x'), new Name('y')))->expand($variables), ); $this->assertSame( '.value', - (new Label(new Name('var')))->expand($variables) + (new Label(new Name('var')))->expand($variables), ); } @@ -57,7 +57,7 @@ public function testOf() { $this->assertInstanceOf( Label::class, - $expression = Label::of(Str::of('{.foo,bar}')) + $expression = Label::of(Str::of('{.foo,bar}')), ); $this->assertSame('{.foo,bar}', $expression->toString()); } @@ -74,7 +74,7 @@ public function testRegex() { $this->assertSame( '\.(?[a-zA-Z0-9\%\-\_\~]*).(?[a-zA-Z0-9\%\-\_\~]*)', - Label::of(Str::of('{.foo,bar}'))->regex() + Label::of(Str::of('{.foo,bar}'))->regex(), ); } } diff --git a/tests/Expression/Level3/ParametersTest.php b/tests/Expression/Level3/ParametersTest.php index 1c8db48..c2c62b3 100644 --- a/tests/Expression/Level3/ParametersTest.php +++ b/tests/Expression/Level3/ParametersTest.php @@ -21,7 +21,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Parameters(new Name('foo'), new Name('bar')) + new Parameters(new Name('foo'), new Name('bar')), ); } @@ -45,11 +45,11 @@ public function testExpand() $this->assertSame( ';x=1024;y=768', - (new Parameters(new Name('x'), new Name('y')))->expand($variables) + (new Parameters(new Name('x'), new Name('y')))->expand($variables), ); $this->assertSame( ';x=1024;y=768;empty', - (new Parameters(new Name('x'), new Name('y'), new Name('empty')))->expand($variables) + (new Parameters(new Name('x'), new Name('y'), new Name('empty')))->expand($variables), ); } @@ -57,7 +57,7 @@ public function testOf() { $this->assertInstanceOf( Parameters::class, - $expression = Parameters::of(Str::of('{;foo,bar}')) + $expression = Parameters::of(Str::of('{;foo,bar}')), ); $this->assertSame('{;foo,bar}', $expression->toString()); } @@ -74,7 +74,7 @@ public function testRegex() { $this->assertSame( '\;foo=?(?[a-zA-Z0-9\%\-\.\_\~]*)\;bar=?(?[a-zA-Z0-9\%\-\.\_\~]*)', - Parameters::of(Str::of('{;foo,bar}'))->regex() + Parameters::of(Str::of('{;foo,bar}'))->regex(), ); } } diff --git a/tests/Expression/Level3/PathTest.php b/tests/Expression/Level3/PathTest.php index d07f3c5..28e60ce 100644 --- a/tests/Expression/Level3/PathTest.php +++ b/tests/Expression/Level3/PathTest.php @@ -21,7 +21,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Path(new Name('foo'), new Name('bar')) + new Path(new Name('foo'), new Name('bar')), ); } @@ -45,11 +45,11 @@ public function testExpand() $this->assertSame( '/value', - (new Path(new Name('var')))->expand($variables) + (new Path(new Name('var')))->expand($variables), ); $this->assertSame( '/value/1024', - (new Path(new Name('var'), new Name('x')))->expand($variables) + (new Path(new Name('var'), new Name('x')))->expand($variables), ); } @@ -57,7 +57,7 @@ public function testOf() { $this->assertInstanceOf( Path::class, - $expression = Path::of(Str::of('{/foo,bar}')) + $expression = Path::of(Str::of('{/foo,bar}')), ); $this->assertSame('{/foo,bar}', $expression->toString()); } @@ -74,7 +74,7 @@ public function testRegex() { $this->assertSame( '/(?[a-zA-Z0-9\%\-\.\_\~]*)/(?[a-zA-Z0-9\%\-\.\_\~]*)', - Path::of(Str::of('{/foo,bar}'))->regex() + Path::of(Str::of('{/foo,bar}'))->regex(), ); } } diff --git a/tests/Expression/Level3/QueryContinuationTest.php b/tests/Expression/Level3/QueryContinuationTest.php index 4729b12..6f224fb 100644 --- a/tests/Expression/Level3/QueryContinuationTest.php +++ b/tests/Expression/Level3/QueryContinuationTest.php @@ -21,7 +21,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new QueryContinuation(new Name('foo'), new Name('bar')) + new QueryContinuation(new Name('foo'), new Name('bar')), ); } @@ -45,11 +45,11 @@ public function testExpand() $this->assertSame( '&x=1024&y=768', - (new QueryContinuation(new Name('x'), new Name('y')))->expand($variables) + (new QueryContinuation(new Name('x'), new Name('y')))->expand($variables), ); $this->assertSame( '&x=1024&y=768&empty=', - (new QueryContinuation(new Name('x'), new Name('y'), new Name('empty')))->expand($variables) + (new QueryContinuation(new Name('x'), new Name('y'), new Name('empty')))->expand($variables), ); } @@ -57,7 +57,7 @@ public function testOf() { $this->assertInstanceOf( QueryContinuation::class, - $expression = QueryContinuation::of(Str::of('{&foo,bar}')) + $expression = QueryContinuation::of(Str::of('{&foo,bar}')), ); $this->assertSame('{&foo,bar}', $expression->toString()); } @@ -74,7 +74,7 @@ public function testRegex() { $this->assertSame( '\&foo=(?[a-zA-Z0-9\%\-\.\_\~]*)\&bar=(?[a-zA-Z0-9\%\-\.\_\~]*)', - QueryContinuation::of(Str::of('{&foo,bar}'))->regex() + QueryContinuation::of(Str::of('{&foo,bar}'))->regex(), ); } } diff --git a/tests/Expression/Level3/QueryTest.php b/tests/Expression/Level3/QueryTest.php index e6bc1ef..7ae5ac3 100644 --- a/tests/Expression/Level3/QueryTest.php +++ b/tests/Expression/Level3/QueryTest.php @@ -21,7 +21,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Query(new Name('foo'), new Name('bar')) + new Query(new Name('foo'), new Name('bar')), ); } @@ -45,11 +45,11 @@ public function testExpand() $this->assertSame( '?x=1024&y=768', - (new Query(new Name('x'), new Name('y')))->expand($variables) + (new Query(new Name('x'), new Name('y')))->expand($variables), ); $this->assertSame( '?x=1024&y=768&empty=', - (new Query(new Name('x'), new Name('y'), new Name('empty')))->expand($variables) + (new Query(new Name('x'), new Name('y'), new Name('empty')))->expand($variables), ); } @@ -57,7 +57,7 @@ public function testOf() { $this->assertInstanceOf( Query::class, - $expression = Query::of(Str::of('{?foo,bar}')) + $expression = Query::of(Str::of('{?foo,bar}')), ); $this->assertSame('{?foo,bar}', $expression->toString()); } @@ -74,7 +74,7 @@ public function testRegex() { $this->assertSame( '\?foo=(?[a-zA-Z0-9\%\-\.\_\~]*)\&bar=(?[a-zA-Z0-9\%\-\.\_\~]*)', - Query::of(Str::of('{?foo,bar}'))->regex() + Query::of(Str::of('{?foo,bar}'))->regex(), ); } } diff --git a/tests/Expression/Level3/ReservedTest.php b/tests/Expression/Level3/ReservedTest.php index ae6e6ae..50eda51 100644 --- a/tests/Expression/Level3/ReservedTest.php +++ b/tests/Expression/Level3/ReservedTest.php @@ -21,7 +21,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Reserved(new Name('foo'), new Name('bar')) + new Reserved(new Name('foo'), new Name('bar')), ); } @@ -45,11 +45,11 @@ public function testExpand() $this->assertSame( '1024,Hello%20World!,768', - (new Reserved(new Name('x'), new Name('hello'), new Name('y')))->expand($variables) + (new Reserved(new Name('x'), new Name('hello'), new Name('y')))->expand($variables), ); $this->assertSame( '/foo/bar,1024', - (new Reserved(new Name('path'), new Name('x')))->expand($variables) + (new Reserved(new Name('path'), new Name('x')))->expand($variables), ); } @@ -57,7 +57,7 @@ public function testOf() { $this->assertInstanceOf( Reserved::class, - $expression = Reserved::of(Str::of('{+foo,bar}')) + $expression = Reserved::of(Str::of('{+foo,bar}')), ); $this->assertSame('{+foo,bar}', $expression->toString()); } @@ -74,7 +74,7 @@ public function testRegex() { $this->assertSame( '(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*),(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)', - Reserved::of(Str::of('{+foo,bar}'))->regex() + Reserved::of(Str::of('{+foo,bar}'))->regex(), ); } } diff --git a/tests/Expression/Level3Test.php b/tests/Expression/Level3Test.php index da16ecc..1971934 100644 --- a/tests/Expression/Level3Test.php +++ b/tests/Expression/Level3Test.php @@ -21,7 +21,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Level3(new Name('foo'), new Name('bar')) + new Level3(new Name('foo'), new Name('bar')), ); } @@ -45,11 +45,11 @@ public function testExpand() $this->assertSame( '1024,768', - (new Level3(new Name('x'), new Name('y')))->expand($variables) + (new Level3(new Name('x'), new Name('y')))->expand($variables), ); $this->assertSame( '1024,Hello%20World%21,768', - (new Level3(new Name('x'), new Name('hello'), new Name('y')))->expand($variables) + (new Level3(new Name('x'), new Name('hello'), new Name('y')))->expand($variables), ); } @@ -57,7 +57,7 @@ public function testOf() { $this->assertInstanceOf( Level3::class, - $expression = Level3::of(Str::of('{foo,bar}')) + $expression = Level3::of(Str::of('{foo,bar}')), ); $this->assertSame('{foo,bar}', $expression->toString()); } @@ -74,7 +74,7 @@ public function testRegex() { $this->assertSame( '(?[a-zA-Z0-9\%\-\.\_\~]*),(?[a-zA-Z0-9\%\-\.\_\~]*)', - Level3::of(Str::of('{foo,bar}'))->regex() + Level3::of(Str::of('{foo,bar}'))->regex(), ); } } diff --git a/tests/Expression/Level4/CompositeTest.php b/tests/Expression/Level4/CompositeTest.php index 6f23767..c872f87 100644 --- a/tests/Expression/Level4/CompositeTest.php +++ b/tests/Expression/Level4/CompositeTest.php @@ -25,8 +25,8 @@ public function testInterface() Expression::class, new Composite( '/', - $this->createMock(Expression::class) - ) + $this->createMock(Expression::class), + ), ); } @@ -37,16 +37,16 @@ public function testStringCast() (new Composite( '/', Path::limit(new Name('var'), 1), - new Level4(new Name('var')) - ))->toString() + new Level4(new Name('var')), + ))->toString(), ); $this->assertSame( '{/list*,path:4}', (new Composite( '/', Path::explode(new Name('list')), - Level4::limit(new Name('path'), 4) - ))->toString() + Level4::limit(new Name('path'), 4), + ))->toString(), ); } @@ -64,16 +64,16 @@ public function testExpand() (new Composite( '/', Path::limit(new Name('var'), 1), - new Level4(new Name('var')) - ))->expand($variables) + new Level4(new Name('var')), + ))->expand($variables), ); $this->assertSame( '/red/green/blue/%2Ffoo', (new Composite( '/', Path::explode(new Name('list')), - Level4::limit(new Name('path'), 4) - ))->expand($variables) + Level4::limit(new Name('path'), 4), + ))->expand($variables), ); } @@ -107,39 +107,39 @@ public function testRegex() { $this->assertSame( '(?[a-zA-Z0-9\%\-\.\_\~]*)\,(?[a-zA-Z0-9\%\-\.\_\~]*)', - Composite::of(Str::of('{var,hello}'))->regex() + Composite::of(Str::of('{var,hello}'))->regex(), ); $this->assertSame( '(?[a-zA-Z0-9\%\-\.\_\~]*)\,(?[a-zA-Z0-9\%\-\.\_\~]{5})', - Composite::of(Str::of('{var,hello:5}'))->regex() + Composite::of(Str::of('{var,hello:5}'))->regex(), ); $this->assertSame( '(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)\,(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]{5})', - Composite::of(Str::of('{+var,hello:5}'))->regex() + Composite::of(Str::of('{+var,hello:5}'))->regex(), ); $this->assertSame( '\#(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)\,(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]{5})', - Composite::of(Str::of('{#var,hello:5}'))->regex() + Composite::of(Str::of('{#var,hello:5}'))->regex(), ); $this->assertSame( '\.(?[a-zA-Z0-9\%\-\.\_\~]*)\.(?[a-zA-Z0-9\%\-\.\_\~]{5})', - Composite::of(Str::of('{.var,hello:5}'))->regex() + Composite::of(Str::of('{.var,hello:5}'))->regex(), ); $this->assertSame( '\/(?[a-zA-Z0-9\%\-\.\_\~]*)\/(?[a-zA-Z0-9\%\-\.\_\~]{5})', - Composite::of(Str::of('{/var,hello:5}'))->regex() + Composite::of(Str::of('{/var,hello:5}'))->regex(), ); $this->assertSame( '\;var=(?[a-zA-Z0-9\%\-\.\_\~]*)\;hello=(?[a-zA-Z0-9\%\-\.\_\~]{5})', - Composite::of(Str::of('{;var,hello:5}'))->regex() + Composite::of(Str::of('{;var,hello:5}'))->regex(), ); $this->assertSame( '\?var=(?[a-zA-Z0-9\%\-\.\_\~]*)\&hello=(?[a-zA-Z0-9\%\-\.\_\~]{5})', - Composite::of(Str::of('{?var,hello:5}'))->regex() + Composite::of(Str::of('{?var,hello:5}'))->regex(), ); $this->assertSame( '\&var=(?[a-zA-Z0-9\%\-\.\_\~]*)\&hello=(?[a-zA-Z0-9\%\-\.\_\~]{5})', - Composite::of(Str::of('{&var,hello:5}'))->regex() + Composite::of(Str::of('{&var,hello:5}'))->regex(), ); } diff --git a/tests/Expression/Level4/FragmentTest.php b/tests/Expression/Level4/FragmentTest.php index a475f52..41b2b93 100644 --- a/tests/Expression/Level4/FragmentTest.php +++ b/tests/Expression/Level4/FragmentTest.php @@ -28,15 +28,15 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Fragment(new Name('foo')) + new Fragment(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - Fragment::explode(new Name('foo')) + Fragment::explode(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - Fragment::limit(new Name('foo'), 42) + Fragment::limit(new Name('foo'), 42), ); } @@ -69,23 +69,23 @@ public function testExpand() $this->assertSame( '#/foo/b', - Fragment::limit(new Name('path'), 6)->expand($variables) + Fragment::limit(new Name('path'), 6)->expand($variables), ); $this->assertSame( '#red,green,blue', - (new Fragment(new Name('list')))->expand($variables) + (new Fragment(new Name('list')))->expand($variables), ); $this->assertSame( '#red,green,blue', - Fragment::explode(new Name('list'))->expand($variables) + Fragment::explode(new Name('list'))->expand($variables), ); $this->assertSame( '#semi,;,dot,.,comma,,', - (new Fragment(new Name('keys')))->expand($variables) + (new Fragment(new Name('keys')))->expand($variables), ); $this->assertSame( '#semi=;,dot=.,comma=,', - Fragment::explode(new Name('keys'))->expand($variables) + Fragment::explode(new Name('keys'))->expand($variables), ); } @@ -93,17 +93,17 @@ public function testOf() { $this->assertInstanceOf( Fragment::class, - $expression = Fragment::of(Str::of('{#foo}')) + $expression = Fragment::of(Str::of('{#foo}')), ); $this->assertSame('{#foo}', $expression->toString()); $this->assertInstanceOf( Fragment::class, - $expression = Fragment::of(Str::of('{#foo*}')) + $expression = Fragment::of(Str::of('{#foo*}')), ); $this->assertSame('{#foo*}', $expression->toString()); $this->assertInstanceOf( Fragment::class, - $expression = Fragment::of(Str::of('{#foo:42}')) + $expression = Fragment::of(Str::of('{#foo:42}')), ); $this->assertSame('{#foo:42}', $expression->toString()); } @@ -127,11 +127,11 @@ public function testRegex() { $this->assertSame( '\#(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)', - Fragment::of(Str::of('{#foo}'))->regex() + Fragment::of(Str::of('{#foo}'))->regex(), ); $this->assertSame( '\#(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]{2})', - Fragment::of(Str::of('{#foo:2}'))->regex() + Fragment::of(Str::of('{#foo:2}'))->regex(), ); } } diff --git a/tests/Expression/Level4/LabelTest.php b/tests/Expression/Level4/LabelTest.php index 2775ecb..fabdb1e 100644 --- a/tests/Expression/Level4/LabelTest.php +++ b/tests/Expression/Level4/LabelTest.php @@ -28,15 +28,15 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Label(new Name('foo')) + new Label(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - Label::explode(new Name('foo')) + Label::explode(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - Label::limit(new Name('foo'), 42) + Label::limit(new Name('foo'), 42), ); } @@ -69,23 +69,23 @@ public function testExpand() $this->assertSame( '.val', - Label::limit(new Name('var'), 3)->expand($variables) + Label::limit(new Name('var'), 3)->expand($variables), ); $this->assertSame( '.red,green,blue', - (new Label(new Name('list')))->expand($variables) + (new Label(new Name('list')))->expand($variables), ); $this->assertSame( '.red.green.blue', - Label::explode(new Name('list'))->expand($variables) + Label::explode(new Name('list'))->expand($variables), ); $this->assertSame( '.semi,%3B,dot,.,comma,%2C', - (new Label(new Name('keys')))->expand($variables) + (new Label(new Name('keys')))->expand($variables), ); $this->assertSame( '.semi=%3B.dot=..comma=%2C', - Label::explode(new Name('keys'))->expand($variables) + Label::explode(new Name('keys'))->expand($variables), ); } @@ -93,17 +93,17 @@ public function testOf() { $this->assertInstanceOf( Label::class, - $expression = Label::of(Str::of('{.foo}')) + $expression = Label::of(Str::of('{.foo}')), ); $this->assertSame('{.foo}', $expression->toString()); $this->assertInstanceOf( Label::class, - $expression = Label::of(Str::of('{.foo*}')) + $expression = Label::of(Str::of('{.foo*}')), ); $this->assertSame('{.foo*}', $expression->toString()); $this->assertInstanceOf( Label::class, - $expression = Label::of(Str::of('{.foo:42}')) + $expression = Label::of(Str::of('{.foo:42}')), ); $this->assertSame('{.foo:42}', $expression->toString()); } @@ -127,11 +127,11 @@ public function testRegex() { $this->assertSame( '\.(?[a-zA-Z0-9\%\-\.\_\~]*)', - Label::of(Str::of('{.foo}'))->regex() + Label::of(Str::of('{.foo}'))->regex(), ); $this->assertSame( '\.(?[a-zA-Z0-9\%\-\.\_\~]{2})', - Label::of(Str::of('{.foo:2}'))->regex() + Label::of(Str::of('{.foo:2}'))->regex(), ); } } diff --git a/tests/Expression/Level4/ParametersTest.php b/tests/Expression/Level4/ParametersTest.php index ae6d2a4..deffe64 100644 --- a/tests/Expression/Level4/ParametersTest.php +++ b/tests/Expression/Level4/ParametersTest.php @@ -28,15 +28,15 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Parameters(new Name('foo')) + new Parameters(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - Parameters::explode(new Name('foo')) + Parameters::explode(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - Parameters::limit(new Name('foo'), 42) + Parameters::limit(new Name('foo'), 42), ); } @@ -69,23 +69,23 @@ public function testExpand() $this->assertSame( ';hello=Hello', - Parameters::limit(new Name('hello'), 5)->expand($variables) + Parameters::limit(new Name('hello'), 5)->expand($variables), ); $this->assertSame( ';list=red,green,blue', - (new Parameters(new Name('list')))->expand($variables) + (new Parameters(new Name('list')))->expand($variables), ); $this->assertSame( ';list=red;list=green;list=blue', - Parameters::explode(new Name('list'))->expand($variables) + Parameters::explode(new Name('list'))->expand($variables), ); $this->assertSame( ';keys=semi,%3B,dot,.,comma,%2C', - (new Parameters(new Name('keys')))->expand($variables) + (new Parameters(new Name('keys')))->expand($variables), ); $this->assertSame( ';semi=%3B;dot=.;comma=%2C', - Parameters::explode(new Name('keys'))->expand($variables) + Parameters::explode(new Name('keys'))->expand($variables), ); } @@ -93,17 +93,17 @@ public function testOf() { $this->assertInstanceOf( Parameters::class, - $expression = Parameters::of(Str::of('{;foo}')) + $expression = Parameters::of(Str::of('{;foo}')), ); $this->assertSame('{;foo}', $expression->toString()); $this->assertInstanceOf( Parameters::class, - $expression = Parameters::of(Str::of('{;foo*}')) + $expression = Parameters::of(Str::of('{;foo*}')), ); $this->assertSame('{;foo*}', $expression->toString()); $this->assertInstanceOf( Parameters::class, - $expression = Parameters::of(Str::of('{;foo:42}')) + $expression = Parameters::of(Str::of('{;foo:42}')), ); $this->assertSame('{;foo:42}', $expression->toString()); } @@ -127,11 +127,11 @@ public function testRegex() { $this->assertSame( '\;foo=(?[a-zA-Z0-9\%\-\.\_\~]*)', - Parameters::of(Str::of('{;foo}'))->regex() + Parameters::of(Str::of('{;foo}'))->regex(), ); $this->assertSame( '\;foo=(?[a-zA-Z0-9\%\-\.\_\~]{2})', - Parameters::of(Str::of('{;foo:2}'))->regex() + Parameters::of(Str::of('{;foo:2}'))->regex(), ); } } diff --git a/tests/Expression/Level4/PathTest.php b/tests/Expression/Level4/PathTest.php index b0e7bf3..cbf3331 100644 --- a/tests/Expression/Level4/PathTest.php +++ b/tests/Expression/Level4/PathTest.php @@ -28,15 +28,15 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Path(new Name('foo')) + new Path(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - Path::explode(new Name('foo')) + Path::explode(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - Path::limit(new Name('foo'), 42) + Path::limit(new Name('foo'), 42), ); } @@ -69,19 +69,19 @@ public function testExpand() $this->assertSame( '/red,green,blue', - (new Path(new Name('list')))->expand($variables) + (new Path(new Name('list')))->expand($variables), ); $this->assertSame( '/red/green/blue', - Path::explode(new Name('list'))->expand($variables) + Path::explode(new Name('list'))->expand($variables), ); $this->assertSame( '/semi,%3B,dot,.,comma,%2C', - (new Path(new Name('keys')))->expand($variables) + (new Path(new Name('keys')))->expand($variables), ); $this->assertSame( '/semi=%3B/dot=./comma=%2C', - Path::explode(new Name('keys'))->expand($variables) + Path::explode(new Name('keys'))->expand($variables), ); } @@ -89,17 +89,17 @@ public function testOf() { $this->assertInstanceOf( Path::class, - $expression = Path::of(Str::of('{/foo}')) + $expression = Path::of(Str::of('{/foo}')), ); $this->assertSame('{/foo}', $expression->toString()); $this->assertInstanceOf( Path::class, - $expression = Path::of(Str::of('{/foo*}')) + $expression = Path::of(Str::of('{/foo*}')), ); $this->assertSame('{/foo*}', $expression->toString()); $this->assertInstanceOf( Path::class, - $expression = Path::of(Str::of('{/foo:42}')) + $expression = Path::of(Str::of('{/foo:42}')), ); $this->assertSame('{/foo:42}', $expression->toString()); } @@ -123,11 +123,11 @@ public function testRegex() { $this->assertSame( '\/(?[a-zA-Z0-9\%\-\.\_\~]*)', - Path::of(Str::of('{/foo}'))->regex() + Path::of(Str::of('{/foo}'))->regex(), ); $this->assertSame( '\/(?[a-zA-Z0-9\%\-\.\_\~]{2})', - Path::of(Str::of('{/foo:2}'))->regex() + Path::of(Str::of('{/foo:2}'))->regex(), ); } } diff --git a/tests/Expression/Level4/QueryContinuationTest.php b/tests/Expression/Level4/QueryContinuationTest.php index 4755e51..d11dc36 100644 --- a/tests/Expression/Level4/QueryContinuationTest.php +++ b/tests/Expression/Level4/QueryContinuationTest.php @@ -28,15 +28,15 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new QueryContinuation(new Name('foo')) + new QueryContinuation(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - QueryContinuation::explode(new Name('foo')) + QueryContinuation::explode(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - QueryContinuation::limit(new Name('foo'), 42) + QueryContinuation::limit(new Name('foo'), 42), ); } @@ -69,23 +69,23 @@ public function testExpand() $this->assertSame( '&var=val', - QueryContinuation::limit(new Name('var'), 3)->expand($variables) + QueryContinuation::limit(new Name('var'), 3)->expand($variables), ); $this->assertSame( '&list=red,green,blue', - (new QueryContinuation(new Name('list')))->expand($variables) + (new QueryContinuation(new Name('list')))->expand($variables), ); $this->assertSame( '&list=red&list=green&list=blue', - QueryContinuation::explode(new Name('list'))->expand($variables) + QueryContinuation::explode(new Name('list'))->expand($variables), ); $this->assertSame( '&keys=semi,%3B,dot,.,comma,%2C', - (new QueryContinuation(new Name('keys')))->expand($variables) + (new QueryContinuation(new Name('keys')))->expand($variables), ); $this->assertSame( '&semi=%3B&dot=.&comma=%2C', - QueryContinuation::explode(new Name('keys'))->expand($variables) + QueryContinuation::explode(new Name('keys'))->expand($variables), ); } @@ -93,17 +93,17 @@ public function testOf() { $this->assertInstanceOf( QueryContinuation::class, - $expression = QueryContinuation::of(Str::of('{&foo}')) + $expression = QueryContinuation::of(Str::of('{&foo}')), ); $this->assertSame('{&foo}', $expression->toString()); $this->assertInstanceOf( QueryContinuation::class, - $expression = QueryContinuation::of(Str::of('{&foo*}')) + $expression = QueryContinuation::of(Str::of('{&foo*}')), ); $this->assertSame('{&foo*}', $expression->toString()); $this->assertInstanceOf( QueryContinuation::class, - $expression = QueryContinuation::of(Str::of('{&foo:42}')) + $expression = QueryContinuation::of(Str::of('{&foo:42}')), ); $this->assertSame('{&foo:42}', $expression->toString()); } @@ -127,11 +127,11 @@ public function testRegex() { $this->assertSame( '\&foo=(?[a-zA-Z0-9\%\-\.\_\~]*)', - QueryContinuation::of(Str::of('{&foo}'))->regex() + QueryContinuation::of(Str::of('{&foo}'))->regex(), ); $this->assertSame( '\&foo=(?[a-zA-Z0-9\%\-\.\_\~]{2})', - QueryContinuation::of(Str::of('{&foo:2}'))->regex() + QueryContinuation::of(Str::of('{&foo:2}'))->regex(), ); } } diff --git a/tests/Expression/Level4/QueryTest.php b/tests/Expression/Level4/QueryTest.php index b7471e2..776113c 100644 --- a/tests/Expression/Level4/QueryTest.php +++ b/tests/Expression/Level4/QueryTest.php @@ -28,15 +28,15 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Query(new Name('foo')) + new Query(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - Query::explode(new Name('foo')) + Query::explode(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - Query::limit(new Name('foo'), 42) + Query::limit(new Name('foo'), 42), ); } @@ -69,23 +69,23 @@ public function testExpand() $this->assertSame( '?var=val', - Query::limit(new Name('var'), 3)->expand($variables) + Query::limit(new Name('var'), 3)->expand($variables), ); $this->assertSame( '?list=red,green,blue', - (new Query(new Name('list')))->expand($variables) + (new Query(new Name('list')))->expand($variables), ); $this->assertSame( '?list=red&list=green&list=blue', - Query::explode(new Name('list'))->expand($variables) + Query::explode(new Name('list'))->expand($variables), ); $this->assertSame( '?keys=semi,%3B,dot,.,comma,%2C', - (new Query(new Name('keys')))->expand($variables) + (new Query(new Name('keys')))->expand($variables), ); $this->assertSame( '?semi=%3B&dot=.&comma=%2C', - Query::explode(new Name('keys'))->expand($variables) + Query::explode(new Name('keys'))->expand($variables), ); } @@ -93,17 +93,17 @@ public function testOf() { $this->assertInstanceOf( Query::class, - $expression = Query::of(Str::of('{?foo}')) + $expression = Query::of(Str::of('{?foo}')), ); $this->assertSame('{?foo}', $expression->toString()); $this->assertInstanceOf( Query::class, - $expression = Query::of(Str::of('{?foo*}')) + $expression = Query::of(Str::of('{?foo*}')), ); $this->assertSame('{?foo*}', $expression->toString()); $this->assertInstanceOf( Query::class, - $expression = Query::of(Str::of('{?foo:42}')) + $expression = Query::of(Str::of('{?foo:42}')), ); $this->assertSame('{?foo:42}', $expression->toString()); } @@ -127,11 +127,11 @@ public function testRegex() { $this->assertSame( '\?foo=(?[a-zA-Z0-9\%\-\.\_\~]*)', - Query::of(Str::of('{?foo}'))->regex() + Query::of(Str::of('{?foo}'))->regex(), ); $this->assertSame( '\?foo=(?[a-zA-Z0-9\%\-\.\_\~]{2})', - Query::of(Str::of('{?foo:2}'))->regex() + Query::of(Str::of('{?foo:2}'))->regex(), ); } } diff --git a/tests/Expression/Level4/ReservedTest.php b/tests/Expression/Level4/ReservedTest.php index 57f8dee..a8c47d0 100644 --- a/tests/Expression/Level4/ReservedTest.php +++ b/tests/Expression/Level4/ReservedTest.php @@ -28,15 +28,15 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Reserved(new Name('foo')) + new Reserved(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - Reserved::explode(new Name('foo')) + Reserved::explode(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - Reserved::limit(new Name('foo'), 42) + Reserved::limit(new Name('foo'), 42), ); } @@ -69,23 +69,23 @@ public function testExpand() $this->assertSame( '/foo/b', - Reserved::limit(new Name('path'), 6)->expand($variables) + Reserved::limit(new Name('path'), 6)->expand($variables), ); $this->assertSame( 'red,green,blue', - (new Reserved(new Name('list')))->expand($variables) + (new Reserved(new Name('list')))->expand($variables), ); $this->assertSame( 'red,green,blue', - Reserved::explode(new Name('list'))->expand($variables) + Reserved::explode(new Name('list'))->expand($variables), ); $this->assertSame( 'semi,;,dot,.,comma,,', - (new Reserved(new Name('keys')))->expand($variables) + (new Reserved(new Name('keys')))->expand($variables), ); $this->assertSame( 'semi=;,dot=.,comma=,', - Reserved::explode(new Name('keys'))->expand($variables) + Reserved::explode(new Name('keys'))->expand($variables), ); } @@ -93,17 +93,17 @@ public function testOf() { $this->assertInstanceOf( Reserved::class, - $expression = Reserved::of(Str::of('{+foo}')) + $expression = Reserved::of(Str::of('{+foo}')), ); $this->assertSame('{+foo}', $expression->toString()); $this->assertInstanceOf( Reserved::class, - $expression = Reserved::of(Str::of('{+foo*}')) + $expression = Reserved::of(Str::of('{+foo*}')), ); $this->assertSame('{+foo*}', $expression->toString()); $this->assertInstanceOf( Reserved::class, - $expression = Reserved::of(Str::of('{+foo:42}')) + $expression = Reserved::of(Str::of('{+foo:42}')), ); $this->assertSame('{+foo:42}', $expression->toString()); } @@ -127,11 +127,11 @@ public function testRegex() { $this->assertSame( '(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)', - Reserved::of(Str::of('{+foo}'))->regex() + Reserved::of(Str::of('{+foo}'))->regex(), ); $this->assertSame( '(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]{2})', - Reserved::of(Str::of('{+foo:2}'))->regex() + Reserved::of(Str::of('{+foo:2}'))->regex(), ); } } diff --git a/tests/Expression/Level4Test.php b/tests/Expression/Level4Test.php index 19f4e61..bbeed1b 100644 --- a/tests/Expression/Level4Test.php +++ b/tests/Expression/Level4Test.php @@ -28,15 +28,15 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Level4(new Name('foo')) + new Level4(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - Level4::explode(new Name('foo')) + Level4::explode(new Name('foo')), ); $this->assertInstanceOf( Expression::class, - Level4::limit(new Name('foo'), 42) + Level4::limit(new Name('foo'), 42), ); } @@ -69,31 +69,31 @@ public function testExpand() $this->assertSame( 'val', - Level4::limit(new Name('var'), 3)->expand($variables) + Level4::limit(new Name('var'), 3)->expand($variables), ); $this->assertSame( 'value', - Level4::limit(new Name('var'), 30)->expand($variables) + Level4::limit(new Name('var'), 30)->expand($variables), ); $this->assertSame( '%2Ffoo', - Level4::limit(new Name('path'), 4)->expand($variables) + Level4::limit(new Name('path'), 4)->expand($variables), ); $this->assertSame( 'red,green,blue', - (new Level4(new Name('list')))->expand($variables) + (new Level4(new Name('list')))->expand($variables), ); $this->assertSame( 'red,green,blue', - Level4::explode(new Name('list'))->expand($variables) + Level4::explode(new Name('list'))->expand($variables), ); $this->assertSame( 'semi,%3B,dot,.,comma,%2C', - (new Level4(new Name('keys')))->expand($variables) + (new Level4(new Name('keys')))->expand($variables), ); $this->assertSame( 'semi=%3B,dot=.,comma=%2C', - Level4::explode(new Name('keys'))->expand($variables) + Level4::explode(new Name('keys'))->expand($variables), ); } @@ -101,17 +101,17 @@ public function testOf() { $this->assertInstanceOf( Level4::class, - $expression = Level4::of(Str::of('{foo}')) + $expression = Level4::of(Str::of('{foo}')), ); $this->assertSame('{foo}', $expression->toString()); $this->assertInstanceOf( Level4::class, - $expression = Level4::of(Str::of('{foo*}')) + $expression = Level4::of(Str::of('{foo*}')), ); $this->assertSame('{foo*}', $expression->toString()); $this->assertInstanceOf( Level4::class, - $expression = Level4::of(Str::of('{foo:42}')) + $expression = Level4::of(Str::of('{foo:42}')), ); $this->assertSame('{foo:42}', $expression->toString()); } @@ -135,11 +135,11 @@ public function testRegex() { $this->assertSame( '(?[a-zA-Z0-9\%\-\.\_\~]*)', - Level4::of(Str::of('{foo}'))->regex() + Level4::of(Str::of('{foo}'))->regex(), ); $this->assertSame( '(?[a-zA-Z0-9\%\-\.\_\~]{2})', - Level4::of(Str::of('{foo:2}'))->regex() + Level4::of(Str::of('{foo:2}'))->regex(), ); } } diff --git a/tests/ExpressionsTest.php b/tests/ExpressionsTest.php index c79e399..2e1cc63 100644 --- a/tests/ExpressionsTest.php +++ b/tests/ExpressionsTest.php @@ -21,7 +21,7 @@ public function testOf($string, $expected) { $this->assertInstanceOf( $expected, - Expressions::of(Str::of($string)) + Expressions::of(Str::of($string)), ); $this->assertSame( $string, diff --git a/tests/UrlEncodeTest.php b/tests/UrlEncodeTest.php index 975dd73..90dab26 100644 --- a/tests/UrlEncodeTest.php +++ b/tests/UrlEncodeTest.php @@ -46,7 +46,7 @@ public function testSafeCharactersAreNotEncoded() '+', ',', ';', - '=' + '=', )) ->then(function(string $char): void { $encode = UrlEncode::allowReservedCharacters(); @@ -61,7 +61,7 @@ public function testSafeCharactersAreNotEncodedEvenWhenInMiddleOfString() $this->assertSame( ':%20)', - $encode(': )') + $encode(': )'), ); } From 8dc7ddcc0e6f19964490852769bf6c0530d460cd Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 24 Jul 2022 17:45:15 +0200 Subject: [PATCH 05/39] remove unnecessary annotations --- src/Expression/Level3.php | 2 -- src/Expression/Level3/Fragment.php | 1 - src/Expression/Level3/Label.php | 1 - src/Expression/Level3/NamedValues.php | 1 - src/Expression/Level3/Path.php | 1 - src/Expression/Level3/Reserved.php | 1 - src/Expression/Level4.php | 4 ---- src/Expression/Level4/Composite.php | 1 - src/Expression/Level4/Parameters.php | 4 ---- src/Expression/Level4/Query.php | 4 ---- src/Expression/Level4/QueryContinuation.php | 4 ---- 11 files changed, 24 deletions(-) diff --git a/src/Expression/Level3.php b/src/Expression/Level3.php index d370778..7a31e75 100644 --- a/src/Expression/Level3.php +++ b/src/Expression/Level3.php @@ -28,9 +28,7 @@ final class Level3 implements Expression public function __construct(Name ...$names) { - /** @var Sequence */ $this->names = Sequence::of(Name::class, ...$names); - /** @var Sequence */ $this->expressions = $this->names->mapTo( Level1::class, static fn(Name $name) => new Level1($name), diff --git a/src/Expression/Level3/Fragment.php b/src/Expression/Level3/Fragment.php index bb52f24..62a31e9 100644 --- a/src/Expression/Level3/Fragment.php +++ b/src/Expression/Level3/Fragment.php @@ -30,7 +30,6 @@ final class Fragment implements Expression public function __construct(Name ...$names) { - /** @var Sequence */ $this->names = Sequence::of(Name::class, ...$names); /** @var Sequence */ $this->expressions = $this->names->mapTo( diff --git a/src/Expression/Level3/Label.php b/src/Expression/Level3/Label.php index 73d89a6..b6698c1 100644 --- a/src/Expression/Level3/Label.php +++ b/src/Expression/Level3/Label.php @@ -30,7 +30,6 @@ final class Label implements Expression public function __construct(Name ...$names) { - /** @var Sequence */ $this->names = Sequence::of(Name::class, ...$names); /** @var Sequence */ $this->expressions = $this->names->mapTo( diff --git a/src/Expression/Level3/NamedValues.php b/src/Expression/Level3/NamedValues.php index 530bd37..3a66b3e 100644 --- a/src/Expression/Level3/NamedValues.php +++ b/src/Expression/Level3/NamedValues.php @@ -31,7 +31,6 @@ public function __construct(string $lead, string $separator, Name ...$names) { $this->lead = $lead; $this->separator = $separator; - /** @var Sequence */ $this->names = Sequence::of(Name::class, ...$names); /** @var Map */ $this->expressions = $this->names->toMapOf( diff --git a/src/Expression/Level3/Path.php b/src/Expression/Level3/Path.php index 0e97a90..bad12d8 100644 --- a/src/Expression/Level3/Path.php +++ b/src/Expression/Level3/Path.php @@ -30,7 +30,6 @@ final class Path implements Expression public function __construct(Name ...$names) { - /** @var Sequence */ $this->names = Sequence::of(Name::class, ...$names); /** @var Sequence */ $this->expressions = $this->names->mapTo( diff --git a/src/Expression/Level3/Reserved.php b/src/Expression/Level3/Reserved.php index 3412069..b60e0f1 100644 --- a/src/Expression/Level3/Reserved.php +++ b/src/Expression/Level3/Reserved.php @@ -30,7 +30,6 @@ final class Reserved implements Expression public function __construct(Name ...$names) { - /** @var Sequence */ $this->names = Sequence::of(Name::class, ...$names); /** @var Sequence */ $this->expressions = $this->names->mapTo( diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index 4a511f1..e8caa6b 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -249,10 +249,6 @@ private function explodeList(Map $variables, array $variablesToExpand): string $expanded = Sequence::of('scalar|array', ...$variablesToExpand) ->map(function($variableToExpand) use ($variables): string { if (\is_array($variableToExpand)) { - /** - * @var string $name - * @var scalar $value - */ [$name, $value] = $variableToExpand; $variableToExpand = $value; } diff --git a/src/Expression/Level4/Composite.php b/src/Expression/Level4/Composite.php index f8349f4..ac87da0 100644 --- a/src/Expression/Level4/Composite.php +++ b/src/Expression/Level4/Composite.php @@ -33,7 +33,6 @@ public function __construct( ) { $this->separator = $separator; $this->type = \get_class($level4); - /** @var Sequence */ $this->expressions = Sequence::of(Expression::class, $level4, ...$expressions); } diff --git a/src/Expression/Level4/Parameters.php b/src/Expression/Level4/Parameters.php index 45cab79..0efdf44 100644 --- a/src/Expression/Level4/Parameters.php +++ b/src/Expression/Level4/Parameters.php @@ -218,10 +218,6 @@ private function explodeList(Map $variables, array $variablesToExpand): string $name = $this->name; if (\is_array($variableToExpand)) { - /** - * @var string $name - * @var scalar $value - */ [$name, $value] = $variableToExpand; $name = new Name($name); $variableToExpand = $value; diff --git a/src/Expression/Level4/Query.php b/src/Expression/Level4/Query.php index dfd61cd..d769179 100644 --- a/src/Expression/Level4/Query.php +++ b/src/Expression/Level4/Query.php @@ -219,10 +219,6 @@ private function explodeList(Map $variables, array $variablesToExpand): string $name = $this->name; if (\is_array($variableToExpand)) { - /** - * @var string $name - * @var scalar $value - */ [$name, $value] = $variableToExpand; $name = new Name($name); $variableToExpand = $value; diff --git a/src/Expression/Level4/QueryContinuation.php b/src/Expression/Level4/QueryContinuation.php index a2b05bb..a9249c7 100644 --- a/src/Expression/Level4/QueryContinuation.php +++ b/src/Expression/Level4/QueryContinuation.php @@ -218,10 +218,6 @@ private function explodeList(Map $variables, array $variablesToExpand): string $name = $this->name; if (\is_array($variableToExpand)) { - /** - * @var string $name - * @var scalar $value - */ [$name, $value] = $variableToExpand; $name = new Name($name); $variableToExpand = $value; From 8e0a57cc6e9aaaa79e1ebdf0c93ad3af184b42bb Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 30 Jul 2022 11:25:09 +0200 Subject: [PATCH 06/39] update dependencies --- composer.json | 4 +- src/Expression/Level1.php | 21 +- src/Expression/Level2/Fragment.php | 21 +- src/Expression/Level2/Reserved.php | 21 +- src/Expression/Level3.php | 44 +-- src/Expression/Level3/Fragment.php | 44 +-- src/Expression/Level3/Label.php | 44 +-- src/Expression/Level3/NamedValues.php | 44 +-- src/Expression/Level3/Parameters.php | 12 +- src/Expression/Level3/Path.php | 47 +-- src/Expression/Level3/Query.php | 12 +- src/Expression/Level3/QueryContinuation.php | 12 +- src/Expression/Level3/Reserved.php | 44 +-- src/Expression/Level4.php | 51 +-- src/Expression/Level4/Composite.php | 64 ++-- src/Expression/Level4/Fragment.php | 3 +- src/Expression/Level4/Label.php | 3 +- src/Expression/Level4/Parameters.php | 50 +-- src/Expression/Level4/Path.php | 3 +- src/Expression/Level4/Query.php | 81 +++-- src/Expression/Level4/QueryContinuation.php | 78 +++-- src/Expression/Level4/Reserved.php | 3 +- src/Template.php | 43 +-- src/UrlEncode.php | 14 +- tests/Expression/Level1Test.php | 8 +- tests/Expression/Level2/FragmentTest.php | 10 +- tests/Expression/Level2/ReservedTest.php | 10 +- tests/Expression/Level3/FragmentTest.php | 2 +- tests/Expression/Level3/LabelTest.php | 2 +- tests/Expression/Level3/ParametersTest.php | 2 +- tests/Expression/Level3/PathTest.php | 2 +- .../Level3/QueryContinuationTest.php | 2 +- tests/Expression/Level3/QueryTest.php | 2 +- tests/Expression/Level3/ReservedTest.php | 2 +- tests/Expression/Level3Test.php | 2 +- tests/Expression/Level4/CompositeTest.php | 4 +- tests/Expression/Level4/FragmentTest.php | 2 +- tests/Expression/Level4/LabelTest.php | 2 +- tests/Expression/Level4/ParametersTest.php | 2 +- tests/Expression/Level4/PathTest.php | 2 +- .../Level4/QueryContinuationTest.php | 2 +- tests/Expression/Level4/QueryTest.php | 2 +- tests/Expression/Level4/ReservedTest.php | 2 +- tests/Expression/Level4Test.php | 2 +- tests/TemplateTest.php | 305 +++++++++++------- 45 files changed, 554 insertions(+), 578 deletions(-) diff --git a/composer.json b/composer.json index 851fdb9..1ec2510 100644 --- a/composer.json +++ b/composer.json @@ -16,8 +16,8 @@ }, "require": { "php": "~8.1", - "innmind/url": "~3.0", - "innmind/immutable": "~3.1" + "innmind/url": "~4.1", + "innmind/immutable": "~4.3" }, "autoload": { "psr-4": { diff --git a/src/Expression/Level1.php b/src/Expression/Level1.php index ca483b5..ced38af 100644 --- a/src/Expression/Level1.php +++ b/src/Expression/Level1.php @@ -38,17 +38,18 @@ public static function of(Str $string): Expression public function expand(Map $variables): string { - if (!$variables->contains($this->name->toString())) { - return ''; - } - - $variable = $variables->get($this->name->toString()); - - if (\is_array($variable)) { - throw new OnlyScalarCanBeExpandedForExpression($this->name->toString()); - } + return $variables + ->get($this->name->toString()) + ->match( + function($variable) { + if (\is_array($variable)) { + throw new OnlyScalarCanBeExpandedForExpression($this->name->toString()); + } - return ($this->encode)((string) $variable); + return ($this->encode)((string) $variable); + }, + static fn() => '', + ); } public function regex(): string diff --git a/src/Expression/Level2/Fragment.php b/src/Expression/Level2/Fragment.php index 61f6b28..a4d423f 100644 --- a/src/Expression/Level2/Fragment.php +++ b/src/Expression/Level2/Fragment.php @@ -39,17 +39,18 @@ public static function of(Str $string): Expression public function expand(Map $variables): string { - if (!$variables->contains($this->name->toString())) { - return ''; - } - - $variable = $variables->get($this->name->toString()); - - if (\is_array($variable)) { - throw new OnlyScalarCanBeExpandedForExpression($this->name->toString()); - } + return $variables + ->get($this->name->toString()) + ->match( + function($variable) { + if (\is_array($variable)) { + throw new OnlyScalarCanBeExpandedForExpression($this->name->toString()); + } - return '#'.($this->encode)((string) $variable); + return '#'.($this->encode)((string) $variable); + }, + static fn() => '', + ); } public function regex(): string diff --git a/src/Expression/Level2/Reserved.php b/src/Expression/Level2/Reserved.php index 63e1a0a..bb31948 100644 --- a/src/Expression/Level2/Reserved.php +++ b/src/Expression/Level2/Reserved.php @@ -39,17 +39,18 @@ public static function of(Str $string): Expression public function expand(Map $variables): string { - if (!$variables->contains($this->name->toString())) { - return ''; - } - - $variable = $variables->get($this->name->toString()); - - if (\is_array($variable)) { - throw new OnlyScalarCanBeExpandedForExpression($this->name->toString()); - } + return $variables + ->get($this->name->toString()) + ->match( + function($variable) { + if (\is_array($variable)) { + throw new OnlyScalarCanBeExpandedForExpression($this->name->toString()); + } - return ($this->encode)((string) $variable); + return ($this->encode)((string) $variable); + }, + static fn() => '', + ); } public function regex(): string diff --git a/src/Expression/Level3.php b/src/Expression/Level3.php index 7a31e75..231c841 100644 --- a/src/Expression/Level3.php +++ b/src/Expression/Level3.php @@ -12,10 +12,6 @@ Sequence, Str, }; -use function Innmind\Immutable\{ - unwrap, - join, -}; final class Level3 implements Expression { @@ -26,11 +22,13 @@ final class Level3 implements Expression private ?string $regex = null; private ?string $string = null; + /** + * @no-named-arguments + */ public function __construct(Name ...$names) { - $this->names = Sequence::of(Name::class, ...$names); - $this->expressions = $this->names->mapTo( - Level1::class, + $this->names = Sequence::of(...$names); + $this->expressions = $this->names->map( static fn(Name $name) => new Level1($name), ); } @@ -41,49 +39,39 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - /** @var Sequence $names */ $names = $string ->trim('{}') ->split(',') - ->reduce( - Sequence::of(Name::class), - static fn(Sequence $names, Str $name): Sequence => ($names)(new Name($name->toString())), - ); + ->map(static fn($name) => new Name($name->toString())); - return new self(...unwrap($names)); + return new self(...$names->toList()); } public function expand(Map $variables): string { - $expanded = $this->expressions->mapTo( - 'string', + $expanded = $this->expressions->map( static fn($expression) => $expression->expand($variables), ); - return join(',', $expanded)->toString(); + return Str::of(',')->join($expanded)->toString(); } public function regex(): string { /** @psalm-suppress InvalidArgument */ - return $this->regex ?? $this->regex = join( - ',', - $this->names->mapTo( - 'string', + return $this->regex ?? $this->regex = Str::of(',') + ->join($this->names->map( static fn(Name $name) => "(?<{$name->toString()}>[a-zA-Z0-9\%\-\.\_\~]*)", - ), - )->toString(); + )) + ->toString(); } public function toString(): string { - return $this->string ?? $this->string = join( - ',', - $this->names->mapTo( - 'string', + return $this->string ?? $this->string = Str::of(',') + ->join($this->names->map( static fn($name) => $name->toString(), - ), - ) + )) ->prepend('{') ->append('}') ->toString(); diff --git a/src/Expression/Level3/Fragment.php b/src/Expression/Level3/Fragment.php index 62a31e9..1f7b5e1 100644 --- a/src/Expression/Level3/Fragment.php +++ b/src/Expression/Level3/Fragment.php @@ -14,10 +14,6 @@ Sequence, Str, }; -use function Innmind\Immutable\{ - join, - unwrap, -}; final class Fragment implements Expression { @@ -28,12 +24,14 @@ final class Fragment implements Expression private ?string $regex = null; private ?string $string = null; + /** + * @no-named-arguments + */ public function __construct(Name ...$names) { - $this->names = Sequence::of(Name::class, ...$names); + $this->names = Sequence::of(...$names); /** @var Sequence */ - $this->expressions = $this->names->mapTo( - Expression::class, + $this->expressions = $this->names->map( static fn(Name $name) => new Level2\Reserved($name), ); } @@ -44,52 +42,42 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - /** @var Sequence $names */ $names = $string ->trim('{#}') ->split(',') - ->reduce( - Sequence::of(Name::class), - static fn(Sequence $names, Str $name): Sequence => ($names)(new Name($name->toString())), - ); + ->map(static fn($name) => new Name($name->toString())); - return new self(...unwrap($names)); + return new self(...$names->toList()); } public function expand(Map $variables): string { - $expanded = $this->expressions->mapTo( - 'string', + $expanded = $this->expressions->map( static fn($expression) => $expression->expand($variables), ); - return join(',', $expanded) + return Str::of(',') + ->join($expanded) ->prepend('#') ->toString(); } public function regex(): string { - return $this->regex ?? $this->regex = join( - ',', - $this->expressions->mapTo( - 'string', + return $this->regex ?? $this->regex = Str::of(',') + ->join($this->expressions->map( static fn($expression) => $expression->regex(), - ), - ) + )) ->prepend('\#') ->toString(); } public function toString(): string { - return $this->string ?? $this->string = join( - ',', - $this->names->mapTo( - 'string', + return $this->string ?? $this->string = Str::of(',') + ->join($this->names->map( static fn($element) => $element->toString(), - ), - ) + )) ->prepend('{#') ->append('}') ->toString(); diff --git a/src/Expression/Level3/Label.php b/src/Expression/Level3/Label.php index b6698c1..14af2d4 100644 --- a/src/Expression/Level3/Label.php +++ b/src/Expression/Level3/Label.php @@ -14,10 +14,6 @@ Sequence, Str, }; -use function Innmind\Immutable\{ - join, - unwrap, -}; final class Label implements Expression { @@ -28,12 +24,14 @@ final class Label implements Expression private ?string $regex = null; private ?string $string = null; + /** + * @no-named-arguments + */ public function __construct(Name ...$names) { - $this->names = Sequence::of(Name::class, ...$names); + $this->names = Sequence::of(...$names); /** @var Sequence */ - $this->expressions = $this->names->mapTo( - Expression::class, + $this->expressions = $this->names->map( static fn(Name $name) => new Level1($name), ); } @@ -44,39 +42,32 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - /** @var Sequence $names */ $names = $string ->trim('{.}') ->split(',') - ->reduce( - Sequence::of(Name::class), - static fn(Sequence $names, Str $name): Sequence => ($names)(new Name($name->toString())), - ); + ->map(static fn($name) => new Name($name->toString())); - return new self(...unwrap($names)); + return new self(...$names->toList()); } public function expand(Map $variables): string { - $expanded = $this->expressions->mapTo( - 'string', + $expanded = $this->expressions->map( static fn($expression) => $expression->expand($variables), ); - return join('.', $expanded) + return Str::of('.') + ->join($expanded) ->prepend('.') ->toString(); } public function regex(): string { - return $this->regex ?? $this->regex = join( - '.', - $this->expressions->mapTo( - 'string', + return $this->regex ?? $this->regex = Str::of('.') + ->join($this->expressions->map( static fn($expression) => $expression->regex(), - ), - ) + )) ->replace('\.', '') ->prepend('\.') ->toString(); @@ -84,13 +75,10 @@ public function regex(): string public function toString(): string { - return $this->string ?? $this->string = join( - ',', - $this->names->mapTo( - 'string', + return $this->string ?? $this->string = Str::of(',') + ->join($this->names->map( static fn($element) => $element->toString(), - ), - ) + )) ->prepend('{.') ->append('}') ->toString(); diff --git a/src/Expression/Level3/NamedValues.php b/src/Expression/Level3/NamedValues.php index 3a66b3e..14eba3a 100644 --- a/src/Expression/Level3/NamedValues.php +++ b/src/Expression/Level3/NamedValues.php @@ -13,7 +13,6 @@ Sequence, Str, }; -use function Innmind\Immutable\join; final class NamedValues implements Expression { @@ -27,16 +26,23 @@ final class NamedValues implements Expression private ?string $regex = null; private ?string $string = null; + /** + * @no-named-arguments + */ public function __construct(string $lead, string $separator, Name ...$names) { $this->lead = $lead; $this->separator = $separator; - $this->names = Sequence::of(Name::class, ...$names); + $this->names = Sequence::of(...$names); /** @var Map */ - $this->expressions = $this->names->toMapOf( - 'string', - Expression::class, - static fn(Name $name): \Generator => yield $name->toString() => new Level1($name), + $this->expressions = Map::of( + ...$this + ->names + ->map(static fn($name) => [ + $name->toString(), + new Level1($name), + ]) + ->toList(), ); } @@ -45,6 +51,9 @@ public static function of(Str $string): Expression throw new \LogicException('should not be used directly'); } + /** + * @no-named-arguments + */ public static function keyOnlyWhenEmpty(string $lead, string $separator, Name ...$names): self { $self = new self($lead, $separator, ...$names); @@ -57,7 +66,7 @@ public function expand(Map $variables): string { /** @var Sequence */ $expanded = $this->expressions->reduce( - Sequence::of('string'), + Sequence::strings(), function(Sequence $expanded, string $name, Expression $expression) use ($variables): Sequence { $value = Str::of($expression->expand($variables)); @@ -69,38 +78,33 @@ function(Sequence $expanded, string $name, Expression $expression) use ($variabl }, ); - return join($this->separator, $expanded) + return Str::of($this->separator) + ->join($expanded) ->prepend($this->lead) ->toString(); } public function regex(): string { - return $this->regex ?? $this->regex = join( - '\\'.$this->separator, - $this->names->mapTo( - 'string', + return $this->regex ?? $this->regex = Str::of('\\'.$this->separator) + ->join($this->names->map( fn($name) => \sprintf( '%s=%s%s', $name->toString(), $this->keyOnlyWhenEmpty ? '?' : '', (new Level1($name))->regex(), ), - ), - ) + )) ->prepend('\\'.$this->lead) ->toString(); } public function toString(): string { - return $this->string ?? $this->string = join( - ',', - $this->names->mapTo( - 'string', + return $this->string ?? $this->string = Str::of(',') + ->join($this->names->map( static fn($element) => $element->toString(), - ), - ) + )) ->prepend('{'.$this->lead) ->append('}') ->toString(); diff --git a/src/Expression/Level3/Parameters.php b/src/Expression/Level3/Parameters.php index 247915d..0340ccd 100644 --- a/src/Expression/Level3/Parameters.php +++ b/src/Expression/Level3/Parameters.php @@ -13,12 +13,14 @@ Sequence, Str, }; -use function Innmind\Immutable\unwrap; final class Parameters implements Expression { private Expression $expression; + /** + * @no-named-arguments + */ public function __construct(Name ...$names) { $this->expression = NamedValues::keyOnlyWhenEmpty(';', ';', ...$names); @@ -30,16 +32,12 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - /** @var Sequence $names */ $names = $string ->trim('{;}') ->split(',') - ->reduce( - Sequence::of(Name::class), - static fn(Sequence $names, Str $name): Sequence => ($names)(new Name($name->toString())), - ); + ->map(static fn($name) => new Name($name->toString())); - return new self(...unwrap($names)); + return new self(...$names->toList()); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Path.php b/src/Expression/Level3/Path.php index bad12d8..d4cd247 100644 --- a/src/Expression/Level3/Path.php +++ b/src/Expression/Level3/Path.php @@ -14,10 +14,6 @@ Sequence, Str, }; -use function Innmind\Immutable\{ - join, - unwrap, -}; final class Path implements Expression { @@ -28,12 +24,14 @@ final class Path implements Expression private ?string $regex = null; private ?string $string = null; + /** + * @no-named-arguments + */ public function __construct(Name ...$names) { - $this->names = Sequence::of(Name::class, ...$names); + $this->names = Sequence::of(...$names); /** @var Sequence */ - $this->expressions = $this->names->mapTo( - Expression::class, + $this->expressions = $this->names->map( static fn(Name $name) => new Level1($name), ); } @@ -44,53 +42,40 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - /** @var Sequence $names */ $names = $string ->trim('{/}') ->split(',') - ->reduce( - Sequence::of(Name::class), - static fn(Sequence $names, Str $name): Sequence => ($names)(new Name($name->toString())), - ); + ->map(static fn($name) => new Name($name->toString())); - return new self(...unwrap($names)); + return new self(...$names->toList()); } public function expand(Map $variables): string { - return join( - '/', - $this->expressions->mapTo( - 'string', + return Str::of('/') + ->join($this->expressions->map( static fn($expression) => $expression->expand($variables), - ), - ) + )) ->prepend('/') ->toString(); } public function regex(): string { - return $this->regex ?? $this->regex = join( - '/', - $this->expressions->mapTo( - 'string', + return $this->regex ?? $this->regex = Str::of('/') + ->join($this->expressions->map( static fn($expression) => $expression->regex(), - ), - ) + )) ->prepend('/') ->toString(); } public function toString(): string { - return $this->string ?? $this->string = join( - ',', - $this->names->mapTo( - 'string', + return $this->string ?? $this->string = Str::of(',') + ->join($this->names->map( static fn($element) => $element->toString(), - ), - ) + )) ->prepend('{/') ->append('}') ->toString(); diff --git a/src/Expression/Level3/Query.php b/src/Expression/Level3/Query.php index a442c23..8df07f7 100644 --- a/src/Expression/Level3/Query.php +++ b/src/Expression/Level3/Query.php @@ -13,12 +13,14 @@ Sequence, Str, }; -use function Innmind\Immutable\unwrap; final class Query implements Expression { private Expression $expression; + /** + * @no-named-arguments + */ public function __construct(Name ...$names) { $this->expression = new NamedValues('?', '&', ...$names); @@ -30,16 +32,12 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - /** @var Sequence $names */ $names = $string ->trim('{?}') ->split(',') - ->reduce( - Sequence::of(Name::class), - static fn(Sequence $names, Str $name): Sequence => ($names)(new Name($name->toString())), - ); + ->map(static fn($name) => new Name($name->toString())); - return new self(...unwrap($names)); + return new self(...$names->toList()); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/QueryContinuation.php b/src/Expression/Level3/QueryContinuation.php index fdb5ee6..0576e3b 100644 --- a/src/Expression/Level3/QueryContinuation.php +++ b/src/Expression/Level3/QueryContinuation.php @@ -13,12 +13,14 @@ Sequence, Str, }; -use function Innmind\Immutable\unwrap; final class QueryContinuation implements Expression { private Expression $expression; + /** + * @no-named-arguments + */ public function __construct(Name ...$names) { $this->expression = new NamedValues('&', '&', ...$names); @@ -30,16 +32,12 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - /** @var Sequence $names */ $names = $string ->trim('{&}') ->split(',') - ->reduce( - Sequence::of(Name::class), - static fn(Sequence $names, Str $name): Sequence => ($names)(new Name($name->toString())), - ); + ->map(static fn($name) => new Name($name->toString())); - return new self(...unwrap($names)); + return new self(...$names->toList()); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Reserved.php b/src/Expression/Level3/Reserved.php index b60e0f1..c4c2cf1 100644 --- a/src/Expression/Level3/Reserved.php +++ b/src/Expression/Level3/Reserved.php @@ -14,10 +14,6 @@ Sequence, Str, }; -use function Innmind\Immutable\{ - join, - unwrap, -}; final class Reserved implements Expression { @@ -28,12 +24,14 @@ final class Reserved implements Expression private ?string $regex = null; private ?string $string = null; + /** + * @no-named-arguments + */ public function __construct(Name ...$names) { - $this->names = Sequence::of(Name::class, ...$names); + $this->names = Sequence::of(...$names); /** @var Sequence */ - $this->expressions = $this->names->mapTo( - Expression::class, + $this->expressions = $this->names->map( static fn(Name $name) => new Level2\Reserved($name), ); } @@ -44,48 +42,38 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - /** @var Sequence $names */ $names = $string ->trim('{+}') ->split(',') - ->reduce( - Sequence::of(Name::class), - static fn(Sequence $names, Str $name): Sequence => ($names)(new Name($name->toString())), - ); + ->map(static fn($name) => new Name($name->toString())); - return new self(...unwrap($names)); + return new self(...$names->toList()); } public function expand(Map $variables): string { - $expanded = $this->expressions->mapTo( - 'string', + $expanded = $this->expressions->map( static fn($expression) => $expression->expand($variables), ); - return join(',', $expanded)->toString(); + return Str::of(',')->join($expanded)->toString(); } public function regex(): string { - return $this->regex ?? $this->regex = join( - ',', - $this->expressions->mapTo( - 'string', + return $this->regex ?? $this->regex = Str::of(',') + ->join($this->expressions->map( static fn($expression) => $expression->regex(), - ), - )->toString(); + )) + ->toString(); } public function toString(): string { - return $this->string ?? $this->string = join( - ',', - $this->names->mapTo( - 'string', + return $this->string ?? $this->string = Str::of(',') + ->join($this->names->map( static fn($element) => $element->toString(), - ), - ) + )) ->prepend('{+') ->append('}') ->toString(); diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index e8caa6b..faa453c 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -15,10 +15,6 @@ Str, Sequence, }; -use function Innmind\Immutable\{ - join, - unwrap, -}; final class Level4 implements Expression { @@ -49,7 +45,7 @@ public static function of(Str $string): Expression if ($string->matches('~^\{[a-zA-Z0-9_]+:\d+\}$~')) { $string = $string->trim('{}'); - [$name, $limit] = unwrap($string->split(':')); + [$name, $limit] = $string->split(':')->toList(); return self::limit( new Name($name->toString()), @@ -125,13 +121,16 @@ public function withExpression(string $expression): self public function expand(Map $variables): string { - if (!$variables->contains($this->name->toString())) { + /** @var scalar|array{0:string, 1:scalar}|null */ + $variable = $variables->get($this->name->toString())->match( + static fn($variable) => $variable, + static fn() => null, + ); + + if (\is_null($variable)) { return ''; } - /** @var scalar|array{0:string, 1:scalar} */ - $variable = $variables->get($this->name->toString()); - if (\is_array($variable)) { return $this->expandList($variables, ...$variable); } @@ -202,6 +201,7 @@ private function mustLimit(): bool } /** + * @no-named-arguments * @param Map $variables * @param array $variablesToExpand */ @@ -211,31 +211,30 @@ private function expandList(Map $variables, ...$variablesToExpand): string return $this->explodeList($variables, $variablesToExpand); } - /** @var Sequence */ - $flattenedVariables = Sequence::of('scalar|array', ...$variablesToExpand)->reduce( - Sequence::of('scalar'), - static function(Sequence $values, $variableToExpand): Sequence { + $flattenedVariables = Sequence::of(...$variablesToExpand)->flatMap( + static function($variableToExpand): Sequence { if (\is_array($variableToExpand)) { [$name, $variableToExpand] = $variableToExpand; - return ($values)($name)($variableToExpand); + return Sequence::of($name, $variableToExpand); } - return ($values)($variableToExpand); + return Sequence::of($variableToExpand); }, ); - $expanded = $flattenedVariables - ->map(function($variableToExpand) use ($variables): string { + $expanded = $flattenedVariables->map( + function($variableToExpand) use ($variables): string { // here we use the level1 expression to transform the variable to // be expanded to its string representation return $this->expression->expand( ($variables)($this->name->toString(), $variableToExpand), ); - }) - ->toSequenceOf('string'); + }, + ); - return join($this->separator, $expanded) + return Str::of($this->separator) + ->join($expanded) ->prepend($this->lead) ->toString(); } @@ -246,8 +245,9 @@ static function(Sequence $values, $variableToExpand): Sequence { */ private function explodeList(Map $variables, array $variablesToExpand): string { - $expanded = Sequence::of('scalar|array', ...$variablesToExpand) - ->map(function($variableToExpand) use ($variables): string { + /** @psalm-suppress NamedArgumentNotAllowed */ + $expanded = Sequence::of(...$variablesToExpand)->map( + function($variableToExpand) use ($variables): string { if (\is_array($variableToExpand)) { [$name, $value] = $variableToExpand; $variableToExpand = $value; @@ -269,10 +269,11 @@ private function explodeList(Map $variables, array $variablesToExpand): string } return $value; - }) - ->toSequenceOf('string'); + }, + ); - return join($this->separator, $expanded) + return Str::of($this->separator) + ->join($expanded) ->prepend($this->lead) ->toString(); } diff --git a/src/Expression/Level4/Composite.php b/src/Expression/Level4/Composite.php index ac87da0..633cd05 100644 --- a/src/Expression/Level4/Composite.php +++ b/src/Expression/Level4/Composite.php @@ -14,7 +14,6 @@ Sequence, Str, }; -use function Innmind\Immutable\join; final class Composite implements Expression { @@ -33,7 +32,7 @@ public function __construct( ) { $this->separator = $separator; $this->type = \get_class($level4); - $this->expressions = Sequence::of(Expression::class, $level4, ...$expressions); + $this->expressions = Sequence::of($level4, ...$expressions); } public static function removeLead( @@ -56,6 +55,10 @@ public static function of(Str $string): Expression $pieces = $string ->trim('{}') ->split(','); + $first = $pieces->first()->match( + static fn($first) => $first, + static fn() => throw new DomainException($string->toString()), + ); /** * @psalm-suppress UndefinedInterfaceMethod @@ -64,7 +67,7 @@ public static function of(Str $string): Expression return $pieces ->drop(1) ->reduce( - Expressions::of($pieces->first()->prepend('{')->append('}')), + Expressions::of($first->prepend('{')->append('}')), static function(Expression $level4, Str $expression): Expression { /** @psalm-suppress MixedReturnStatement */ return $level4->add($expression); @@ -74,8 +77,7 @@ static function(Expression $level4, Str $expression): Expression { public function expand(Map $variables): string { - $expanded = $this->expressions->mapTo( - 'string', + $expanded = $this->expressions->map( static fn($expression) => $expression->expand($variables), ); @@ -94,7 +96,7 @@ public function expand(Map $variables): string }), ); - return join($this->separator, $expanded)->toString(); + return Str::of($this->separator)->join($expanded)->toString(); } public function regex(): string @@ -106,28 +108,23 @@ public function regex(): string $remaining = $this ->expressions ->drop(1) - ->mapTo( - 'string', - function(Expression $expression): string { - if ($this->removeLead) { - return Str::of($expression->regex())->substring(2)->toString(); - } - - return $expression->regex(); - }, - ); - - return $this->regex = join( - $this->separator ? '\\'.$this->separator : '', - $this - ->expressions - ->take(1) - ->mapTo( - 'string', - static fn($expression) => $expression->regex(), - ) - ->append($remaining), - )->toString(); + ->map(function(Expression $expression): string { + if ($this->removeLead) { + return Str::of($expression->regex())->substring(2)->toString(); + } + + return $expression->regex(); + }); + + return $this->regex = Str::of($this->separator ? '\\'.$this->separator : '') + ->join( + $this + ->expressions + ->take(1) + ->map(static fn($expression) => $expression->regex()) + ->append($remaining), + ) + ->toString(); } public function toString(): string @@ -136,8 +133,7 @@ public function toString(): string return $this->string; } - $expressions = $this->expressions->mapTo( - Str::class, + $expressions = $this->expressions->map( static fn($expression) => Str::of($expression->toString())->trim('{}'), ); @@ -153,12 +149,10 @@ public function toString(): string return $expression->leftTrim('+#/.;?&'); }), ) - ->mapTo( - 'string', - static fn($element) => $element->toString(), - ); + ->map(static fn($element) => $element->toString()); - return $this->string = join(',', $expressions) + return $this->string = Str::of(',') + ->join($expressions) ->prepend('{') ->append('}') ->toString(); diff --git a/src/Expression/Level4/Fragment.php b/src/Expression/Level4/Fragment.php index 42fa2a9..f8cdc22 100644 --- a/src/Expression/Level4/Fragment.php +++ b/src/Expression/Level4/Fragment.php @@ -16,7 +16,6 @@ Map, Str, }; -use function Innmind\Immutable\unwrap; final class Fragment implements Expression { @@ -41,7 +40,7 @@ public static function of(Str $string): Expression if ($string->matches('~^\{#[a-zA-Z0-9_]+:\d+\}$~')) { $string = $string->trim('{#}'); - [$name, $limit] = unwrap($string->split(':')); + [$name, $limit] = $string->split(':')->toList(); return self::limit( new Name($name->toString()), diff --git a/src/Expression/Level4/Label.php b/src/Expression/Level4/Label.php index 84721c9..6c36208 100644 --- a/src/Expression/Level4/Label.php +++ b/src/Expression/Level4/Label.php @@ -15,7 +15,6 @@ Map, Str, }; -use function Innmind\Immutable\unwrap; final class Label implements Expression { @@ -38,7 +37,7 @@ public static function of(Str $string): Expression if ($string->matches('~^\{\.[a-zA-Z0-9_]+:\d+\}$~')) { $string = $string->trim('{.}'); - [$name, $limit] = unwrap($string->split(':')); + [$name, $limit] = $string->split(':')->toList(); return self::limit( new Name($name->toString()), diff --git a/src/Expression/Level4/Parameters.php b/src/Expression/Level4/Parameters.php index 0efdf44..111bb68 100644 --- a/src/Expression/Level4/Parameters.php +++ b/src/Expression/Level4/Parameters.php @@ -18,10 +18,6 @@ Str, Sequence, }; -use function Innmind\Immutable\{ - join, - unwrap, -}; final class Parameters implements Expression { @@ -50,7 +46,7 @@ public static function of(Str $string): Expression if ($string->matches('~^\{;[a-zA-Z0-9_]+:\d+\}$~')) { $string = $string->trim('{;}'); - [$name, $limit] = unwrap($string->split(':')); + [$name, $limit] = $string->split(':')->toList(); return self::limit( new Name($name->toString()), @@ -95,13 +91,16 @@ public function add(Str $pattern): Composite */ public function expand(Map $variables): string { - if (!$variables->contains($this->name->toString())) { + /** @var scalar|array{0:string, 1:scalar}|null */ + $variable = $variables->get($this->name->toString())->match( + static fn($variable) => $variable, + static fn() => null, + ); + + if (\is_null($variable)) { return ''; } - /** @var scalar|array{0:string, 1:scalar} */ - $variable = $variables->get($this->name->toString()); - if (\is_array($variable)) { return $this->expandList($variables, ...$variable); } @@ -169,6 +168,7 @@ private function mustLimit(): bool } /** + * @no-named-arguments * @param Map $variables * @param array $variablesToExpand */ @@ -178,31 +178,30 @@ private function expandList(Map $variables, ...$variablesToExpand): string return $this->explodeList($variables, $variablesToExpand); } - /** @var Sequence */ - $flattenedVariables = Sequence::of('scalar|array', ...$variablesToExpand)->reduce( - Sequence::of('scalar'), - static function(Sequence $values, $variableToExpand): Sequence { + $flattenedVariables = Sequence::of(...$variablesToExpand)->flatMap( + static function($variableToExpand): Sequence { if (\is_array($variableToExpand)) { [$name, $variableToExpand] = $variableToExpand; - return ($values)($name)($variableToExpand); + return Sequence::of($name, $variableToExpand); } - return ($values)($variableToExpand); + return Sequence::of($variableToExpand); }, ); - $expanded = $flattenedVariables - ->map(function($variableToExpand) use ($variables): string { + $expanded = $flattenedVariables->map( + function($variableToExpand) use ($variables): string { // here we use the level1 expression to transform the variable to // be expanded to its string representation /** @psalm-suppress MixedArgument */ $variables = ($variables)($this->name->toString(), $variableToExpand); return $this->expression->expand($variables); - }) - ->toSequenceOf('string'); + }, + ); - return join(',', $expanded) + return Str::of(',') + ->join($expanded) ->prepend(";{$this->name->toString()}=") ->toString(); } @@ -213,8 +212,9 @@ static function(Sequence $values, $variableToExpand): Sequence { */ private function explodeList(Map $variables, array $variablesToExpand): string { - $expanded = Sequence::of('scalar|array', ...$variablesToExpand) - ->map(function($variableToExpand) use ($variables): string { + /** @psalm-suppress NamedArgumentNotAllowed */ + $expanded = Sequence::of(...$variablesToExpand)->map( + function($variableToExpand) use ($variables): string { $name = $this->name; if (\is_array($variableToExpand)) { @@ -227,9 +227,9 @@ private function explodeList(Map $variables, array $variablesToExpand): string $variables = ($variables)($name->toString(), $variableToExpand); return (new Level3\Parameters($name))->expand($variables); - }) - ->toSequenceOf('string'); + }, + ); - return join('', $expanded)->toString(); + return Str::of('')->join($expanded)->toString(); } } diff --git a/src/Expression/Level4/Path.php b/src/Expression/Level4/Path.php index eb40380..170668d 100644 --- a/src/Expression/Level4/Path.php +++ b/src/Expression/Level4/Path.php @@ -15,7 +15,6 @@ Map, Str, }; -use function Innmind\Immutable\unwrap; final class Path implements Expression { @@ -38,7 +37,7 @@ public static function of(Str $string): Expression if ($string->matches('~^\{/[a-zA-Z0-9_]+:\d+\}$~')) { $string = $string->trim('{/}'); - [$name, $limit] = unwrap($string->split(':')); + [$name, $limit] = $string->split(':')->toList(); return self::limit( new Name($name->toString()), diff --git a/src/Expression/Level4/Query.php b/src/Expression/Level4/Query.php index d769179..53c5491 100644 --- a/src/Expression/Level4/Query.php +++ b/src/Expression/Level4/Query.php @@ -18,10 +18,6 @@ Str, Sequence, }; -use function Innmind\Immutable\{ - join, - unwrap, -}; final class Query implements Expression { @@ -50,7 +46,7 @@ public static function of(Str $string): Expression if ($string->matches('~^\{\?[a-zA-Z0-9_]+:\d+\}$~')) { $string = $string->trim('{?}'); - [$name, $limit] = unwrap($string->split(':')); + [$name, $limit] = $string->split(':')->toList(); return self::limit( new Name($name->toString()), @@ -95,13 +91,16 @@ public function add(Str $pattern): Composite */ public function expand(Map $variables): string { - if (!$variables->contains($this->name->toString())) { + /** @var scalar|array{0:string, 1:scalar}|null */ + $variable = $variables->get($this->name->toString())->match( + static fn($variable) => $variable, + static fn() => null, + ); + + if (\is_null($variable)) { return ''; } - /** @var scalar|array{0:string, 1:scalar} */ - $variable = $variables->get($this->name->toString()); - if (\is_array($variable)) { return $this->expandList($variables, ...$variable); } @@ -169,6 +168,7 @@ private function mustLimit(): bool } /** + * @no-named-arguments * @param Map $variables * @param array $variablesToExpand */ @@ -178,32 +178,29 @@ private function expandList(Map $variables, ...$variablesToExpand): string return $this->explodeList($variables, $variablesToExpand); } - /** @var Sequence */ - $flattenedVariables = Sequence::of('scalar|array', ...$variablesToExpand)->reduce( - Sequence::of('scalar'), - static function(Sequence $values, $variableToExpand): Sequence { + $flattenedVariables = Sequence::of(...$variablesToExpand)->flatMap( + static function($variableToExpand): Sequence { if (\is_array($variableToExpand)) { [$name, $variableToExpand] = $variableToExpand; - return ($values)($name)($variableToExpand); + return Sequence::of($name, $variableToExpand); } - return ($values)($variableToExpand); + return Sequence::of($variableToExpand); }, ); - $expanded = $flattenedVariables - ->map(function($variableToExpand) use ($variables): string { - // here we use the level1 expression to transform the variable to - // be expanded to its string representation + $expanded = $flattenedVariables->map(function($variableToExpand) use ($variables): string { + // here we use the level1 expression to transform the variable to + // be expanded to its string representation - /** @psalm-suppress MixedArgument */ - $variables = ($variables)($this->name->toString(), $variableToExpand); + /** @psalm-suppress MixedArgument */ + $variables = ($variables)($this->name->toString(), $variableToExpand); - return $this->expression->expand($variables); - }) - ->toSequenceOf('string'); + return $this->expression->expand($variables); + }); - return join(',', $expanded) + return Str::of(',') + ->join($expanded) ->prepend("?{$this->name->toString()}=") ->toString(); } @@ -214,28 +211,28 @@ static function(Sequence $values, $variableToExpand): Sequence { */ private function explodeList(Map $variables, array $variablesToExpand): string { - $expanded = Sequence::of('scalar|array', ...$variablesToExpand) - ->map(function($variableToExpand) use ($variables): string { - $name = $this->name; + /** @psalm-suppress NamedArgumentNotAllowed */ + $expanded = Sequence::of(...$variablesToExpand)->map(function($variableToExpand) use ($variables): string { + $name = $this->name; - if (\is_array($variableToExpand)) { - [$name, $value] = $variableToExpand; - $name = new Name($name); - $variableToExpand = $value; - } + if (\is_array($variableToExpand)) { + [$name, $value] = $variableToExpand; + $name = new Name($name); + $variableToExpand = $value; + } - /** @psalm-suppress MixedArgument */ - $variables = ($variables)($name->toString(), $variableToExpand); + /** @psalm-suppress MixedArgument */ + $variables = ($variables)($name->toString(), $variableToExpand); - $value = (new Level3\Query($name))->expand($variables); + $value = (new Level3\Query($name))->expand($variables); - // the substring is here to remove the '?' as it should be a '&' - // done below in the join - return Str::of($value)->substring(1)->toString(); - }) - ->toSequenceOf('string'); + // the substring is here to remove the '?' as it should be a '&' + // done below in the join + return Str::of($value)->substring(1)->toString(); + }); - return join('&', $expanded) + return Str::of('&') + ->join($expanded) ->prepend('?') ->toString(); } diff --git a/src/Expression/Level4/QueryContinuation.php b/src/Expression/Level4/QueryContinuation.php index a9249c7..7a276ed 100644 --- a/src/Expression/Level4/QueryContinuation.php +++ b/src/Expression/Level4/QueryContinuation.php @@ -18,10 +18,6 @@ Str, Sequence, }; -use function Innmind\Immutable\{ - join, - unwrap, -}; final class QueryContinuation implements Expression { @@ -50,7 +46,7 @@ public static function of(Str $string): Expression if ($string->matches('~^\{\&[a-zA-Z0-9_]+:\d+\}$~')) { $string = $string->trim('{&}'); - [$name, $limit] = unwrap($string->split(':')); + [$name, $limit] = $string->split(':')->toList(); return self::limit( new Name($name->toString()), @@ -95,13 +91,16 @@ public function add(Str $pattern): Composite */ public function expand(Map $variables): string { - if (!$variables->contains($this->name->toString())) { + /** @var scalar|array{0:string, 1:scalar}|null */ + $variable = $variables->get($this->name->toString())->match( + static fn($variable) => $variable, + static fn() => null, + ); + + if (\is_null($variable)) { return ''; } - /** @var scalar|array{0:string, 1:scalar} */ - $variable = $variables->get($this->name->toString()); - if (\is_array($variable)) { return $this->expandList($variables, ...$variable); } @@ -169,6 +168,7 @@ private function mustLimit(): bool } /** + * @no-named-arguments * @param Map $variables * @param array $variablesToExpand */ @@ -178,31 +178,28 @@ private function expandList(Map $variables, ...$variablesToExpand): string return $this->explodeList($variables, $variablesToExpand); } - /** @var Sequence */ - $flattenedVariables = Sequence::of('scalar|array', ...$variablesToExpand)->reduce( - Sequence::of('scalar'), - static function(Sequence $values, $variableToExpand): Sequence { + $flattenedVariables = Sequence::of(...$variablesToExpand)->flatMap( + static function($variableToExpand): Sequence { if (\is_array($variableToExpand)) { [$name, $variableToExpand] = $variableToExpand; - return ($values)($name)($variableToExpand); + return Sequence::of($name, $variableToExpand); } - return ($values)($variableToExpand); + return Sequence::of($variableToExpand); }, ); - $expanded = $flattenedVariables - ->map(function($variableToExpand) use ($variables): string { - // here we use the level1 expression to transform the variable to - // be expanded to its string representation - /** @psalm-suppress MixedArgument */ - $variables = ($variables)($this->name->toString(), $variableToExpand); - - return $this->expression->expand($variables); - }) - ->toSequenceOf('string'); - - return join(',', $expanded) + $expanded = $flattenedVariables->map(function($variableToExpand) use ($variables): string { + // here we use the level1 expression to transform the variable to + // be expanded to its string representation + /** @psalm-suppress MixedArgument */ + $variables = ($variables)($this->name->toString(), $variableToExpand); + + return $this->expression->expand($variables); + }); + + return Str::of(',') + ->join($expanded) ->prepend("&{$this->name->toString()}=") ->toString(); } @@ -213,23 +210,22 @@ static function(Sequence $values, $variableToExpand): Sequence { */ private function explodeList(Map $variables, array $variablesToExpand): string { - $expanded = Sequence::of('scalar|array', ...$variablesToExpand) - ->map(function($variableToExpand) use ($variables): string { - $name = $this->name; + /** @psalm-suppress NamedArgumentNotAllowed */ + $expanded = Sequence::of(...$variablesToExpand)->map(function($variableToExpand) use ($variables): string { + $name = $this->name; - if (\is_array($variableToExpand)) { - [$name, $value] = $variableToExpand; - $name = new Name($name); - $variableToExpand = $value; - } + if (\is_array($variableToExpand)) { + [$name, $value] = $variableToExpand; + $name = new Name($name); + $variableToExpand = $value; + } - /** @psalm-suppress MixedArgument */ - $variables = ($variables)($name->toString(), $variableToExpand); + /** @psalm-suppress MixedArgument */ + $variables = ($variables)($name->toString(), $variableToExpand); - return (new Level3\QueryContinuation($name))->expand($variables); - }) - ->toSequenceOf('string'); + return (new Level3\QueryContinuation($name))->expand($variables); + }); - return join('', $expanded)->toString(); + return Str::of('')->join($expanded)->toString(); } } diff --git a/src/Expression/Level4/Reserved.php b/src/Expression/Level4/Reserved.php index b74d033..216bf6d 100644 --- a/src/Expression/Level4/Reserved.php +++ b/src/Expression/Level4/Reserved.php @@ -16,7 +16,6 @@ Map, Str, }; -use function Innmind\Immutable\unwrap; final class Reserved implements Expression { @@ -47,7 +46,7 @@ public static function of(Str $string): Expression if ($string->matches('~^\{\+[a-zA-Z0-9_]+:\d+\}$~')) { $string = $string->trim('{+}'); - [$name, $limit] = unwrap($string->split(':')); + [$name, $limit] = $string->split(':')->toList(); return self::limit( new Name($name->toString()), diff --git a/src/Template.php b/src/Template.php index 105cadf..5b15859 100644 --- a/src/Template.php +++ b/src/Template.php @@ -14,7 +14,6 @@ Sequence, Str, }; -use function Innmind\Immutable\assertMap; final class Template { @@ -27,13 +26,11 @@ private function __construct(string $template) $this->template = Str::of($template); $this->expressions = $this ->extractExpressions( - Sequence::of('string'), + Sequence::of(), $this->template, ) - ->mapTo( - Expression::class, - static fn(string $expression) => Expressions::of(Str::of($expression)), - ); + ->map(Str::of(...)) + ->map(Expressions::of(...)); } public static function of(string $template): self @@ -46,8 +43,6 @@ public static function of(string $template): self */ public function expand(Map $variables): Url { - assertMap('string', 'scalar|array', $variables, 1); - $url = $this->expressions->reduce( $this->template, static function(Str $template, Expression $expression) use ($variables): Str { @@ -76,18 +71,8 @@ public function extract(Url $url): Map /** @var Map */ return $url ->capture($regex) - ->filter(static function($key): bool { - return \is_string($key); - }) - ->reduce( - Map::of('string', 'string'), - static function(Map $variables, $name, Str $variable): Map { - return ($variables)( - (string) $name, - \rawurldecode($variable->toString()), - ); - }, - ); + ->filter(static fn($key) => \is_string($key)) + ->map(static fn($_, $variable) => \rawurldecode($variable->toString())); } public function matches(Url $url): bool @@ -116,14 +101,16 @@ private function extractExpressions( ): Sequence { $captured = $template->capture('~(\{[\+#\./;\?&]?[a-zA-Z0-9_]+(\*|:\d+)?(,[a-zA-Z0-9_]+(\*|:\d+)?)*\})~'); - if ($captured->size() === 0) { - return $expressions; - } - - return $this->extractExpressions( - $expressions->add($captured->values()->first()->toString()), - $template->replace($captured->values()->first()->toString(), ''), - ); + return $captured + ->values() + ->first() + ->match( + fn($value) => $this->extractExpressions( + $expressions->add($value->toString()), + $template->replace($value->toString(), ''), + ), + static fn() => $expressions, + ); } private function regex(): string diff --git a/src/UrlEncode.php b/src/UrlEncode.php index b75df39..699ccf6 100644 --- a/src/UrlEncode.php +++ b/src/UrlEncode.php @@ -4,7 +4,6 @@ namespace Innmind\UrlTemplate; use Innmind\Immutable\Str; -use function Innmind\Immutable\join; final class UrlEncode { @@ -26,15 +25,10 @@ public function __invoke(string $string): string if ($string->length() > 1) { $characters = $string ->split() - ->map(function(Str $character): Str { - return Str::of($this($character->toString())); - }) - ->mapTo( - 'string', - static fn(Str $character): string => $character->toString(), - ); - - return join('', $characters)->toString(); + ->map(fn($character) => Str::of($this($character->toString()))) + ->map(static fn($character) => $character->toString()); + + return Str::of('')->join($characters)->toString(); } if ($string->empty()) { diff --git a/tests/Expression/Level1Test.php b/tests/Expression/Level1Test.php index f86215e..2005883 100644 --- a/tests/Expression/Level1Test.php +++ b/tests/Expression/Level1Test.php @@ -36,13 +36,13 @@ public function testExpand() $expression = new Level1(new Name('foo')); $this->assertSame('value', $expression->expand( - Map::of('string', 'variable')('foo', 'value'), + Map::of(['foo', 'value']), )); $this->assertSame('Hello%20World%21', $expression->expand( - Map::of('string', 'variable')('foo', 'Hello World!'), + Map::of(['foo', 'Hello World!']), )); $this->assertSame('', $expression->expand( - Map::of('string', 'variable'), + Map::of(), )); } @@ -79,7 +79,7 @@ public function testThrowWhenTryingToExpandWithAnArray() $this->expectExceptionMessage('foo'); $expression->expand( - Map::of('string', 'variable')('foo', ['value']), + Map::of(['foo', ['value']]), ); } } diff --git a/tests/Expression/Level2/FragmentTest.php b/tests/Expression/Level2/FragmentTest.php index 6407c41..c571ba4 100644 --- a/tests/Expression/Level2/FragmentTest.php +++ b/tests/Expression/Level2/FragmentTest.php @@ -36,16 +36,16 @@ public function testExpand() $expression = new Fragment(new Name('foo')); $this->assertSame('#value', $expression->expand( - Map::of('string', 'variable')('foo', 'value'), + Map::of(['foo', 'value']), )); $this->assertSame('#Hello%20World!', $expression->expand( - Map::of('string', 'variable')('foo', 'Hello World!'), + Map::of(['foo', 'Hello World!']), )); $this->assertSame('#/foo/bar', $expression->expand( - Map::of('string', 'variable')('foo', '/foo/bar'), + Map::of(['foo', '/foo/bar']), )); $this->assertSame('', $expression->expand( - Map::of('string', 'variable'), + Map::of(), )); } @@ -82,7 +82,7 @@ public function testThrowWhenTryingToExpandWithAnArray() $this->expectExceptionMessage('foo'); $expression->expand( - Map::of('string', 'variable')('foo', ['value']), + Map::of(['foo', ['value']]), ); } } diff --git a/tests/Expression/Level2/ReservedTest.php b/tests/Expression/Level2/ReservedTest.php index a3bccd9..1ac3523 100644 --- a/tests/Expression/Level2/ReservedTest.php +++ b/tests/Expression/Level2/ReservedTest.php @@ -36,16 +36,16 @@ public function testExpand() $expression = new Reserved(new Name('foo')); $this->assertSame('value', $expression->expand( - Map::of('string', 'variable')('foo', 'value'), + Map::of(['foo', 'value']), )); $this->assertSame('Hello%20World!', $expression->expand( - Map::of('string', 'variable')('foo', 'Hello World!'), + Map::of(['foo', 'Hello World!']), )); $this->assertSame('/foo/bar', $expression->expand( - Map::of('string', 'variable')('foo', '/foo/bar'), + Map::of(['foo', '/foo/bar']), )); $this->assertSame('', $expression->expand( - Map::of('string', 'variable'), + Map::of(), )); } @@ -82,7 +82,7 @@ public function testThrowWhenTryingToExpandWithAnArray() $this->expectExceptionMessage('foo'); $expression->expand( - Map::of('string', 'variable')('foo', ['value']), + Map::of(['foo', ['value']]), ); } } diff --git a/tests/Expression/Level3/FragmentTest.php b/tests/Expression/Level3/FragmentTest.php index 3b0fd2c..e51ca6e 100644 --- a/tests/Expression/Level3/FragmentTest.php +++ b/tests/Expression/Level3/FragmentTest.php @@ -35,7 +35,7 @@ public function testStringCast() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('empty', '') diff --git a/tests/Expression/Level3/LabelTest.php b/tests/Expression/Level3/LabelTest.php index 465dac8..f4c279c 100644 --- a/tests/Expression/Level3/LabelTest.php +++ b/tests/Expression/Level3/LabelTest.php @@ -35,7 +35,7 @@ public function testStringCast() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('empty', '') diff --git a/tests/Expression/Level3/ParametersTest.php b/tests/Expression/Level3/ParametersTest.php index c2c62b3..cbc7309 100644 --- a/tests/Expression/Level3/ParametersTest.php +++ b/tests/Expression/Level3/ParametersTest.php @@ -35,7 +35,7 @@ public function testStringCast() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('empty', '') diff --git a/tests/Expression/Level3/PathTest.php b/tests/Expression/Level3/PathTest.php index 28e60ce..070bb7d 100644 --- a/tests/Expression/Level3/PathTest.php +++ b/tests/Expression/Level3/PathTest.php @@ -35,7 +35,7 @@ public function testStringCast() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('empty', '') diff --git a/tests/Expression/Level3/QueryContinuationTest.php b/tests/Expression/Level3/QueryContinuationTest.php index 6f224fb..3c67e83 100644 --- a/tests/Expression/Level3/QueryContinuationTest.php +++ b/tests/Expression/Level3/QueryContinuationTest.php @@ -35,7 +35,7 @@ public function testStringCast() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('empty', '') diff --git a/tests/Expression/Level3/QueryTest.php b/tests/Expression/Level3/QueryTest.php index 7ae5ac3..d5f29eb 100644 --- a/tests/Expression/Level3/QueryTest.php +++ b/tests/Expression/Level3/QueryTest.php @@ -35,7 +35,7 @@ public function testStringCast() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('empty', '') diff --git a/tests/Expression/Level3/ReservedTest.php b/tests/Expression/Level3/ReservedTest.php index 50eda51..37ab006 100644 --- a/tests/Expression/Level3/ReservedTest.php +++ b/tests/Expression/Level3/ReservedTest.php @@ -35,7 +35,7 @@ public function testStringCast() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('empty', '') diff --git a/tests/Expression/Level3Test.php b/tests/Expression/Level3Test.php index 1971934..d319f0a 100644 --- a/tests/Expression/Level3Test.php +++ b/tests/Expression/Level3Test.php @@ -35,7 +35,7 @@ public function testStringCast() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('empty', '') diff --git a/tests/Expression/Level4/CompositeTest.php b/tests/Expression/Level4/CompositeTest.php index c872f87..16e34da 100644 --- a/tests/Expression/Level4/CompositeTest.php +++ b/tests/Expression/Level4/CompositeTest.php @@ -52,7 +52,7 @@ public function testStringCast() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('path', '/foo/bar') @@ -82,7 +82,7 @@ public function testExpand() */ public function testOf($pattern, $expected) { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('path', '/foo/bar') diff --git a/tests/Expression/Level4/FragmentTest.php b/tests/Expression/Level4/FragmentTest.php index 41b2b93..2bd1365 100644 --- a/tests/Expression/Level4/FragmentTest.php +++ b/tests/Expression/Level4/FragmentTest.php @@ -60,7 +60,7 @@ public function testThrowWhenNegativeLimit() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('path', '/foo/bar') diff --git a/tests/Expression/Level4/LabelTest.php b/tests/Expression/Level4/LabelTest.php index fabdb1e..ce062e8 100644 --- a/tests/Expression/Level4/LabelTest.php +++ b/tests/Expression/Level4/LabelTest.php @@ -60,7 +60,7 @@ public function testThrowWhenNegativeLimit() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('path', '/foo/bar') diff --git a/tests/Expression/Level4/ParametersTest.php b/tests/Expression/Level4/ParametersTest.php index deffe64..ddce300 100644 --- a/tests/Expression/Level4/ParametersTest.php +++ b/tests/Expression/Level4/ParametersTest.php @@ -60,7 +60,7 @@ public function testThrowWhenNegativeLimit() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('path', '/foo/bar') diff --git a/tests/Expression/Level4/PathTest.php b/tests/Expression/Level4/PathTest.php index cbf3331..f6253d7 100644 --- a/tests/Expression/Level4/PathTest.php +++ b/tests/Expression/Level4/PathTest.php @@ -60,7 +60,7 @@ public function testThrowWhenNegativeLimit() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('path', '/foo/bar') diff --git a/tests/Expression/Level4/QueryContinuationTest.php b/tests/Expression/Level4/QueryContinuationTest.php index d11dc36..2ca8a36 100644 --- a/tests/Expression/Level4/QueryContinuationTest.php +++ b/tests/Expression/Level4/QueryContinuationTest.php @@ -60,7 +60,7 @@ public function testThrowWhenNegativeLimit() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('path', '/foo/bar') diff --git a/tests/Expression/Level4/QueryTest.php b/tests/Expression/Level4/QueryTest.php index 776113c..e021d4c 100644 --- a/tests/Expression/Level4/QueryTest.php +++ b/tests/Expression/Level4/QueryTest.php @@ -60,7 +60,7 @@ public function testThrowWhenNegativeLimit() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('path', '/foo/bar') diff --git a/tests/Expression/Level4/ReservedTest.php b/tests/Expression/Level4/ReservedTest.php index a8c47d0..b50aab4 100644 --- a/tests/Expression/Level4/ReservedTest.php +++ b/tests/Expression/Level4/ReservedTest.php @@ -60,7 +60,7 @@ public function testThrowWhenNegativeLimit() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('path', '/foo/bar') diff --git a/tests/Expression/Level4Test.php b/tests/Expression/Level4Test.php index bbeed1b..f2b6438 100644 --- a/tests/Expression/Level4Test.php +++ b/tests/Expression/Level4Test.php @@ -60,7 +60,7 @@ public function testThrowWhenNegativeLimit() public function testExpand() { - $variables = Map::of('string', 'variable') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('path', '/foo/bar') diff --git a/tests/TemplateTest.php b/tests/TemplateTest.php index 0927047..35959c3 100644 --- a/tests/TemplateTest.php +++ b/tests/TemplateTest.php @@ -37,7 +37,7 @@ public function testOf() */ public function testExpand($pattern, $expected) { - $variables = Map::of('string', 'scalar|array') + $variables = Map::of() ('var', 'value') ('hello', 'Hello World!') ('path', '/foo/bar') @@ -58,22 +58,6 @@ public function testExpand($pattern, $expected) $this->assertSame($expected, $url->toString()); } - public function testThrowWhenInvalidVariablesKeyType() - { - $this->expectException(\TypeError::class); - $this->expectExceptionMessage('Argument 1 must be of type Map'); - - Template::of('foo')->expand(Map::of('int', 'scalar|array')); - } - - public function testThrowWhenInvalidVariablesValueType() - { - $this->expectException(\TypeError::class); - $this->expectExceptionMessage('Argument 1 must be of type Map'); - - Template::of('foo')->expand(Map::of('string', 'string')); - } - public function testThrowWhenUrlDoesntMatchTemplate() { $this->expectException(UrlDoesntMatchTemplate::class); @@ -87,11 +71,15 @@ public function testLevel1Extraction() $variables = Template::of('/{foo}/{bar}')->extract(Url::of('/hello%20world%21/foo')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(2, $variables); - $this->assertSame('hello world!', $variables->get('foo')); - $this->assertSame('foo', $variables->get('bar')); + $this->assertSame('hello world!', $variables->get('foo')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('foo', $variables->get('bar')->match( + static fn($value) => $value, + static fn() => null, + )); } public function testLevel2Extraction() @@ -99,18 +87,20 @@ public function testLevel2Extraction() $variables = Template::of('{+path}/here')->extract(Url::of('/foo/bar/here')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(1, $variables); - $this->assertSame('/foo/bar', $variables->get('path')); + $this->assertSame('/foo/bar', $variables->get('path')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('X{#hello}')->extract(Url::of('X#Hello%20World!')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(1, $variables); - $this->assertSame('Hello World!', $variables->get('hello')); + $this->assertSame('Hello World!', $variables->get('hello')->match( + static fn($value) => $value, + static fn() => null, + )); } public function testLevel3Extraction() @@ -118,133 +108,204 @@ public function testLevel3Extraction() $variables = Template::of('/map?{x,y}')->extract(Url::of('/map?1024,768')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(2, $variables); - $this->assertSame('1024', $variables->get('x')); - $this->assertSame('768', $variables->get('y')); + $this->assertSame('1024', $variables->get('x')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('768', $variables->get('y')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('/{x,hello,y}')->extract(Url::of('/1024,Hello%20World%21,768')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(3, $variables); - $this->assertSame('1024', $variables->get('x')); - $this->assertSame('Hello World!', $variables->get('hello')); - $this->assertSame('768', $variables->get('y')); + $this->assertSame('1024', $variables->get('x')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('Hello World!', $variables->get('hello')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('768', $variables->get('y')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('/{+x,hello,y}')->extract(Url::of('/1024,Hello%20World!,768')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(3, $variables); - $this->assertSame('1024', $variables->get('x')); - $this->assertSame('Hello World!', $variables->get('hello')); - $this->assertSame('768', $variables->get('y')); + $this->assertSame('1024', $variables->get('x')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('Hello World!', $variables->get('hello')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('768', $variables->get('y')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{+path,x}/here')->extract(Url::of('/foo/bar,1024/here')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(2, $variables); - $this->assertSame('1024', $variables->get('x')); - $this->assertSame('/foo/bar', $variables->get('path')); + $this->assertSame('1024', $variables->get('x')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('/foo/bar', $variables->get('path')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{#x,hello,y}')->extract(Url::of('#1024,Hello%20World!,768')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(3, $variables); - $this->assertSame('1024', $variables->get('x')); - $this->assertSame('Hello World!', $variables->get('hello')); - $this->assertSame('768', $variables->get('y')); + $this->assertSame('1024', $variables->get('x')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('Hello World!', $variables->get('hello')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('768', $variables->get('y')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{#path,x}/here')->extract(Url::of('#/foo/bar,1024/here')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(2, $variables); - $this->assertSame('1024', $variables->get('x')); - $this->assertSame('/foo/bar', $variables->get('path')); + $this->assertSame('1024', $variables->get('x')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('/foo/bar', $variables->get('path')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{.x,y}')->extract(Url::of('.1024.768')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(2, $variables); - $this->assertSame('1024', $variables->get('x')); - $this->assertSame('768', $variables->get('y')); + $this->assertSame('1024', $variables->get('x')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('768', $variables->get('y')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{/var,x}/here')->extract(Url::of('/value/1024/here')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(2, $variables); - $this->assertSame('value', $variables->get('var')); - $this->assertSame('1024', $variables->get('x')); + $this->assertSame('value', $variables->get('var')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('1024', $variables->get('x')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{;x,y}')->extract(Url::of(';x=1024;y=768')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(2, $variables); - $this->assertSame('1024', $variables->get('x')); - $this->assertSame('768', $variables->get('y')); + $this->assertSame('1024', $variables->get('x')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('768', $variables->get('y')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{;x,y,empty}')->extract(Url::of(';x=1024;y=768;empty')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(3, $variables); - $this->assertSame('1024', $variables->get('x')); - $this->assertSame('768', $variables->get('y')); - $this->assertSame('', $variables->get('empty')); + $this->assertSame('1024', $variables->get('x')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('768', $variables->get('y')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('', $variables->get('empty')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{?x,y}')->extract(Url::of('?x=1024&y=768')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(2, $variables); - $this->assertSame('1024', $variables->get('x')); - $this->assertSame('768', $variables->get('y')); + $this->assertSame('1024', $variables->get('x')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('768', $variables->get('y')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{?x,y,empty}')->extract(Url::of('?x=1024&y=768&empty=')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(3, $variables); - $this->assertSame('1024', $variables->get('x')); - $this->assertSame('768', $variables->get('y')); - $this->assertSame('', $variables->get('empty')); + $this->assertSame('1024', $variables->get('x')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('768', $variables->get('y')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('', $variables->get('empty')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('?fixed=yes{&x}')->extract(Url::of('?fixed=yes&x=1024')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(1, $variables); - $this->assertSame('1024', $variables->get('x')); + $this->assertSame('1024', $variables->get('x')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{&x,y,empty}')->extract(Url::of('&x=1024&y=768&empty=')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(3, $variables); - $this->assertSame('1024', $variables->get('x')); - $this->assertSame('768', $variables->get('y')); - $this->assertSame('', $variables->get('empty')); + $this->assertSame('1024', $variables->get('x')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('768', $variables->get('y')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('', $variables->get('empty')->match( + static fn($value) => $value, + static fn() => null, + )); } public function testLevel4Extraction() @@ -252,66 +313,74 @@ public function testLevel4Extraction() $variables = Template::of('{var:3}')->extract(Url::of('val')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(1, $variables); - $this->assertSame('val', $variables->get('var')); + $this->assertSame('val', $variables->get('var')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{+path:6}/here')->extract(Url::of('/foo/b/here')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(1, $variables); - $this->assertSame('/foo/b', $variables->get('path')); + $this->assertSame('/foo/b', $variables->get('path')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{#path:6}/here')->extract(Url::of('#/foo/b/here')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(1, $variables); - $this->assertSame('/foo/b', $variables->get('path')); + $this->assertSame('/foo/b', $variables->get('path')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{.var:3}')->extract(Url::of('.val')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(1, $variables); - $this->assertSame('val', $variables->get('var')); + $this->assertSame('val', $variables->get('var')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{/var:1}')->extract(Url::of('/v')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(1, $variables); - $this->assertSame('v', $variables->get('var')); + $this->assertSame('v', $variables->get('var')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{;var:5}')->extract(Url::of(';var=hello')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(1, $variables); - $this->assertSame('hello', $variables->get('var')); + $this->assertSame('hello', $variables->get('var')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{?var:3}')->extract(Url::of('?var=hel')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(1, $variables); - $this->assertSame('hel', $variables->get('var')); + $this->assertSame('hel', $variables->get('var')->match( + static fn($value) => $value, + static fn() => null, + )); $variables = Template::of('{&var:3}')->extract(Url::of('&var=hel')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(1, $variables); - $this->assertSame('hel', $variables->get('var')); + $this->assertSame('hel', $variables->get('var')->match( + static fn($value) => $value, + static fn() => null, + )); } public function testExtraction() @@ -320,11 +389,15 @@ public function testExtraction() ->extract(Url::of('http://example.com/search?q=chien&lang=fr')); $this->assertInstanceOf(Map::class, $variables); - $this->assertSame('string', (string) $variables->keyType()); - $this->assertSame('string', (string) $variables->valueType()); $this->assertCount(2, $variables); - $this->assertSame('chien', $variables->get('q')); - $this->assertSame('fr', $variables->get('lang')); + $this->assertSame('chien', $variables->get('q')->match( + static fn($value) => $value, + static fn() => null, + )); + $this->assertSame('fr', $variables->get('lang')->match( + static fn($value) => $value, + static fn() => null, + )); } public function testThrowWhenExtractionNotSupportedForTemplate() From 702c8c04066382cc6fbb0f3e2827009f50013f46 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 30 Jul 2022 11:43:22 +0200 Subject: [PATCH 07/39] declare all objects immutable --- src/Expression.php | 5 ++++ src/Expression/Level1.php | 12 +++++--- src/Expression/Level2/Fragment.php | 12 +++++--- src/Expression/Level2/Reserved.php | 12 +++++--- src/Expression/Level3.php | 12 +++++--- src/Expression/Level3/Fragment.php | 12 +++++--- src/Expression/Level3/Label.php | 12 +++++--- src/Expression/Level3/NamedValues.php | 13 ++++++--- src/Expression/Level3/Parameters.php | 6 ++++ src/Expression/Level3/Path.php | 12 +++++--- src/Expression/Level3/Query.php | 6 ++++ src/Expression/Level3/QueryContinuation.php | 6 ++++ src/Expression/Level3/Reserved.php | 12 +++++--- src/Expression/Level4.php | 30 ++++++++++--------- src/Expression/Level4/Composite.php | 23 +++++++-------- src/Expression/Level4/Fragment.php | 30 +++++++++++++------ src/Expression/Level4/Label.php | 12 ++++++++ src/Expression/Level4/Parameters.php | 30 ++++++++++--------- src/Expression/Level4/Path.php | 12 ++++++++ src/Expression/Level4/Query.php | 30 ++++++++++--------- src/Expression/Level4/QueryContinuation.php | 30 ++++++++++--------- src/Expression/Level4/Reserved.php | 32 +++++++++++---------- src/Expression/Name.php | 3 ++ src/Expressions.php | 15 ++++++---- src/Template.php | 6 ++++ src/UrlEncode.php | 6 ++++ 26 files changed, 258 insertions(+), 133 deletions(-) diff --git a/src/Expression.php b/src/Expression.php index 18fb611..0868971 100644 --- a/src/Expression.php +++ b/src/Expression.php @@ -12,9 +12,14 @@ Str, }; +/** + * @psalm-immutable + */ interface Expression { /** + * @psalm-pure + * * @throws DomainException */ public static function of(Str $string): self; diff --git a/src/Expression/Level1.php b/src/Expression/Level1.php index ced38af..42bee39 100644 --- a/src/Expression/Level1.php +++ b/src/Expression/Level1.php @@ -14,12 +14,13 @@ Str, }; +/** + * @psalm-immutable + */ final class Level1 implements Expression { private Name $name; private UrlEncode $encode; - private ?string $regex = null; - private ?string $string = null; public function __construct(Name $name) { @@ -27,6 +28,9 @@ public function __construct(Name $name) $this->encode = new UrlEncode; } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if (!$string->matches('~^\{[a-zA-Z0-9_]+\}$~')) { @@ -54,11 +58,11 @@ function($variable) { public function regex(): string { - return $this->regex ?? $this->regex = "(?<{$this->name->toString()}>[a-zA-Z0-9\%\-\.\_\~]*)"; + return "(?<{$this->name->toString()}>[a-zA-Z0-9\%\-\.\_\~]*)"; } public function toString(): string { - return $this->string ?? $this->string = "{{$this->name->toString()}}"; + return "{{$this->name->toString()}}"; } } diff --git a/src/Expression/Level2/Fragment.php b/src/Expression/Level2/Fragment.php index a4d423f..e7f5093 100644 --- a/src/Expression/Level2/Fragment.php +++ b/src/Expression/Level2/Fragment.php @@ -15,12 +15,13 @@ Str, }; +/** + * @psalm-immutable + */ final class Fragment implements Expression { private Name $name; private UrlEncode $encode; - private ?string $regex = null; - private ?string $string = null; public function __construct(Name $name) { @@ -28,6 +29,9 @@ public function __construct(Name $name) $this->encode = UrlEncode::allowReservedCharacters(); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if (!$string->matches('~^\{#[a-zA-Z0-9_]+\}$~')) { @@ -55,11 +59,11 @@ function($variable) { public function regex(): string { - return $this->regex ?? $this->regex = "\#(?<{$this->name->toString()}>[a-zA-Z0-9\%:/\?#\[\]@!\$&'\(\)\*\+,;=\-\.\_\~]*)"; + return "\#(?<{$this->name->toString()}>[a-zA-Z0-9\%:/\?#\[\]@!\$&'\(\)\*\+,;=\-\.\_\~]*)"; } public function toString(): string { - return $this->string ?? $this->string = "{#{$this->name->toString()}}"; + return "{#{$this->name->toString()}}"; } } diff --git a/src/Expression/Level2/Reserved.php b/src/Expression/Level2/Reserved.php index bb31948..f4c5228 100644 --- a/src/Expression/Level2/Reserved.php +++ b/src/Expression/Level2/Reserved.php @@ -15,12 +15,13 @@ Str, }; +/** + * @psalm-immutable + */ final class Reserved implements Expression { private Name $name; private UrlEncode $encode; - private ?string $regex = null; - private ?string $string = null; public function __construct(Name $name) { @@ -28,6 +29,9 @@ public function __construct(Name $name) $this->encode = UrlEncode::allowReservedCharacters(); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if (!$string->matches('~^\{\+[a-zA-Z0-9_]+\}$~')) { @@ -55,11 +59,11 @@ function($variable) { public function regex(): string { - return $this->regex ?? $this->regex = "(?<{$this->name->toString()}>[a-zA-Z0-9\%:/\?#\[\]@!\$&'\(\)\*\+,;=\-\.\_\~]*)"; + return "(?<{$this->name->toString()}>[a-zA-Z0-9\%:/\?#\[\]@!\$&'\(\)\*\+,;=\-\.\_\~]*)"; } public function toString(): string { - return $this->string ?? $this->string = "{+{$this->name->toString()}}"; + return"{+{$this->name->toString()}}"; } } diff --git a/src/Expression/Level3.php b/src/Expression/Level3.php index 231c841..bedeaef 100644 --- a/src/Expression/Level3.php +++ b/src/Expression/Level3.php @@ -13,14 +13,15 @@ Str, }; +/** + * @psalm-immutable + */ final class Level3 implements Expression { /** @var Sequence */ private Sequence $names; /** @var Sequence */ private Sequence $expressions; - private ?string $regex = null; - private ?string $string = null; /** * @no-named-arguments @@ -33,6 +34,9 @@ public function __construct(Name ...$names) ); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if (!$string->matches('~^\{[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { @@ -59,7 +63,7 @@ public function expand(Map $variables): string public function regex(): string { /** @psalm-suppress InvalidArgument */ - return $this->regex ?? $this->regex = Str::of(',') + return Str::of(',') ->join($this->names->map( static fn(Name $name) => "(?<{$name->toString()}>[a-zA-Z0-9\%\-\.\_\~]*)", )) @@ -68,7 +72,7 @@ public function regex(): string public function toString(): string { - return $this->string ?? $this->string = Str::of(',') + return Str::of(',') ->join($this->names->map( static fn($name) => $name->toString(), )) diff --git a/src/Expression/Level3/Fragment.php b/src/Expression/Level3/Fragment.php index 1f7b5e1..d97a852 100644 --- a/src/Expression/Level3/Fragment.php +++ b/src/Expression/Level3/Fragment.php @@ -15,14 +15,15 @@ Str, }; +/** + * @psalm-immutable + */ final class Fragment implements Expression { /** @var Sequence */ private Sequence $names; /** @var Sequence */ private Sequence $expressions; - private ?string $regex = null; - private ?string $string = null; /** * @no-named-arguments @@ -36,6 +37,9 @@ public function __construct(Name ...$names) ); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if (!$string->matches('~^\{#[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { @@ -64,7 +68,7 @@ public function expand(Map $variables): string public function regex(): string { - return $this->regex ?? $this->regex = Str::of(',') + return Str::of(',') ->join($this->expressions->map( static fn($expression) => $expression->regex(), )) @@ -74,7 +78,7 @@ public function regex(): string public function toString(): string { - return $this->string ?? $this->string = Str::of(',') + return Str::of(',') ->join($this->names->map( static fn($element) => $element->toString(), )) diff --git a/src/Expression/Level3/Label.php b/src/Expression/Level3/Label.php index 14af2d4..bc5ed8b 100644 --- a/src/Expression/Level3/Label.php +++ b/src/Expression/Level3/Label.php @@ -15,14 +15,15 @@ Str, }; +/** + * @psalm-immutable + */ final class Label implements Expression { /** @var Sequence */ private Sequence $names; /** @var Sequence */ private Sequence $expressions; - private ?string $regex = null; - private ?string $string = null; /** * @no-named-arguments @@ -36,6 +37,9 @@ public function __construct(Name ...$names) ); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if (!$string->matches('~^\{\.[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { @@ -64,7 +68,7 @@ public function expand(Map $variables): string public function regex(): string { - return $this->regex ?? $this->regex = Str::of('.') + return Str::of('.') ->join($this->expressions->map( static fn($expression) => $expression->regex(), )) @@ -75,7 +79,7 @@ public function regex(): string public function toString(): string { - return $this->string ?? $this->string = Str::of(',') + return Str::of(',') ->join($this->names->map( static fn($element) => $element->toString(), )) diff --git a/src/Expression/Level3/NamedValues.php b/src/Expression/Level3/NamedValues.php index 14eba3a..a4b1467 100644 --- a/src/Expression/Level3/NamedValues.php +++ b/src/Expression/Level3/NamedValues.php @@ -14,6 +14,9 @@ Str, }; +/** + * @psalm-immutable + */ final class NamedValues implements Expression { private string $lead; @@ -23,8 +26,6 @@ final class NamedValues implements Expression /** @var Map */ private Map $expressions; private bool $keyOnlyWhenEmpty = false; - private ?string $regex = null; - private ?string $string = null; /** * @no-named-arguments @@ -46,6 +47,9 @@ public function __construct(string $lead, string $separator, Name ...$names) ); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { throw new \LogicException('should not be used directly'); @@ -53,6 +57,7 @@ public static function of(Str $string): Expression /** * @no-named-arguments + * @psalm-pure */ public static function keyOnlyWhenEmpty(string $lead, string $separator, Name ...$names): self { @@ -86,7 +91,7 @@ function(Sequence $expanded, string $name, Expression $expression) use ($variabl public function regex(): string { - return $this->regex ?? $this->regex = Str::of('\\'.$this->separator) + return Str::of('\\'.$this->separator) ->join($this->names->map( fn($name) => \sprintf( '%s=%s%s', @@ -101,7 +106,7 @@ public function regex(): string public function toString(): string { - return $this->string ?? $this->string = Str::of(',') + return Str::of(',') ->join($this->names->map( static fn($element) => $element->toString(), )) diff --git a/src/Expression/Level3/Parameters.php b/src/Expression/Level3/Parameters.php index 0340ccd..28d4eac 100644 --- a/src/Expression/Level3/Parameters.php +++ b/src/Expression/Level3/Parameters.php @@ -14,6 +14,9 @@ Str, }; +/** + * @psalm-immutable + */ final class Parameters implements Expression { private Expression $expression; @@ -26,6 +29,9 @@ public function __construct(Name ...$names) $this->expression = NamedValues::keyOnlyWhenEmpty(';', ';', ...$names); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if (!$string->matches('~^\{;[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { diff --git a/src/Expression/Level3/Path.php b/src/Expression/Level3/Path.php index d4cd247..aaab953 100644 --- a/src/Expression/Level3/Path.php +++ b/src/Expression/Level3/Path.php @@ -15,14 +15,15 @@ Str, }; +/** + * @psalm-immutable + */ final class Path implements Expression { /** @var Sequence */ private Sequence $names; /** @var Sequence */ private Sequence $expressions; - private ?string $regex = null; - private ?string $string = null; /** * @no-named-arguments @@ -36,6 +37,9 @@ public function __construct(Name ...$names) ); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if (!$string->matches('~^\{/[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { @@ -62,7 +66,7 @@ public function expand(Map $variables): string public function regex(): string { - return $this->regex ?? $this->regex = Str::of('/') + return Str::of('/') ->join($this->expressions->map( static fn($expression) => $expression->regex(), )) @@ -72,7 +76,7 @@ public function regex(): string public function toString(): string { - return $this->string ?? $this->string = Str::of(',') + return Str::of(',') ->join($this->names->map( static fn($element) => $element->toString(), )) diff --git a/src/Expression/Level3/Query.php b/src/Expression/Level3/Query.php index 8df07f7..2b0abda 100644 --- a/src/Expression/Level3/Query.php +++ b/src/Expression/Level3/Query.php @@ -14,6 +14,9 @@ Str, }; +/** + * @psalm-immutable + */ final class Query implements Expression { private Expression $expression; @@ -26,6 +29,9 @@ public function __construct(Name ...$names) $this->expression = new NamedValues('?', '&', ...$names); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if (!$string->matches('~^\{\?[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { diff --git a/src/Expression/Level3/QueryContinuation.php b/src/Expression/Level3/QueryContinuation.php index 0576e3b..550628d 100644 --- a/src/Expression/Level3/QueryContinuation.php +++ b/src/Expression/Level3/QueryContinuation.php @@ -14,6 +14,9 @@ Str, }; +/** + * @psalm-immutable + */ final class QueryContinuation implements Expression { private Expression $expression; @@ -26,6 +29,9 @@ public function __construct(Name ...$names) $this->expression = new NamedValues('&', '&', ...$names); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if (!$string->matches('~^\{\&[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { diff --git a/src/Expression/Level3/Reserved.php b/src/Expression/Level3/Reserved.php index c4c2cf1..9d19a4a 100644 --- a/src/Expression/Level3/Reserved.php +++ b/src/Expression/Level3/Reserved.php @@ -15,14 +15,15 @@ Str, }; +/** + * @psalm-immutable + */ final class Reserved implements Expression { /** @var Sequence */ private Sequence $names; /** @var Sequence */ private Sequence $expressions; - private ?string $regex = null; - private ?string $string = null; /** * @no-named-arguments @@ -36,6 +37,9 @@ public function __construct(Name ...$names) ); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if (!$string->matches('~^\{\+[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { @@ -61,7 +65,7 @@ public function expand(Map $variables): string public function regex(): string { - return $this->regex ?? $this->regex = Str::of(',') + return Str::of(',') ->join($this->expressions->map( static fn($expression) => $expression->regex(), )) @@ -70,7 +74,7 @@ public function regex(): string public function toString(): string { - return $this->string ?? $this->string = Str::of(',') + return Str::of(',') ->join($this->names->map( static fn($element) => $element->toString(), )) diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index faa453c..ff4b607 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -16,6 +16,9 @@ Sequence, }; +/** + * @psalm-immutable + */ final class Level4 implements Expression { private Name $name; @@ -24,8 +27,6 @@ final class Level4 implements Expression private bool $explode = false; private string $lead = ''; private string $separator = ','; - private ?string $regex = null; - private ?string $string = null; public function __construct(Name $name) { @@ -33,6 +34,9 @@ public function __construct(Name $name) $this->expression = new Level1($name); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if ($string->matches('~^\{[a-zA-Z0-9_]+\}$~')) { @@ -56,6 +60,9 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } + /** + * @psalm-pure + */ public static function limit(Name $name, int $limit): self { if ($limit < 0) { @@ -68,6 +75,9 @@ public static function limit(Name $name, int $limit): self return $self; } + /** + * @psalm-pure + */ public static function explode(Name $name): self { $self = new self($name); @@ -153,10 +163,6 @@ public function expand(Map $variables): string public function regex(): string { - if (\is_string($this->regex)) { - return $this->regex; - } - if ($this->explode) { throw new ExplodeExpressionCantBeMatched; } @@ -171,7 +177,7 @@ public function regex(): string $regex = $this->expression->regex(); } - return $this->regex = \sprintf( + return \sprintf( '%s%s', $this->lead ? '\\'.$this->lead : '', $regex, @@ -180,19 +186,15 @@ public function regex(): string public function toString(): string { - if (\is_string($this->string)) { - return $this->string; - } - if ($this->mustLimit()) { - return $this->string = "{{$this->lead}{$this->name->toString()}:{$this->limit}}"; + return "{{$this->lead}{$this->name->toString()}:{$this->limit}}"; } if ($this->explode) { - return $this->string = "{{$this->lead}{$this->name->toString()}*}"; + return "{{$this->lead}{$this->name->toString()}*}"; } - return $this->string = "{{$this->lead}{$this->name->toString()}}"; + return "{{$this->lead}{$this->name->toString()}}"; } private function mustLimit(): bool diff --git a/src/Expression/Level4/Composite.php b/src/Expression/Level4/Composite.php index 633cd05..1f5b747 100644 --- a/src/Expression/Level4/Composite.php +++ b/src/Expression/Level4/Composite.php @@ -15,6 +15,9 @@ Str, }; +/** + * @psalm-immutable + */ final class Composite implements Expression { private string $separator; @@ -22,8 +25,6 @@ final class Composite implements Expression /** @var Sequence */ private Sequence $expressions; private bool $removeLead = false; - private ?string $regex = null; - private ?string $string = null; public function __construct( string $separator, @@ -35,6 +36,9 @@ public function __construct( $this->expressions = Sequence::of($level4, ...$expressions); } + /** + * @psalm-pure + */ public static function removeLead( string $separator, Expression $level4, @@ -46,6 +50,9 @@ public static function removeLead( return $self; } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if (!$string->matches('~^\{[\+#\./;\?&]?[a-zA-Z0-9_]+(\*|:\d*)?(,[a-zA-Z0-9_]+(\*|:\d*)?)+\}$~')) { @@ -101,10 +108,6 @@ public function expand(Map $variables): string public function regex(): string { - if (\is_string($this->regex)) { - return $this->regex; - } - $remaining = $this ->expressions ->drop(1) @@ -116,7 +119,7 @@ public function regex(): string return $expression->regex(); }); - return $this->regex = Str::of($this->separator ? '\\'.$this->separator : '') + return Str::of($this->separator ? '\\'.$this->separator : '') ->join( $this ->expressions @@ -129,10 +132,6 @@ public function regex(): string public function toString(): string { - if (\is_string($this->string)) { - return $this->string; - } - $expressions = $this->expressions->map( static fn($expression) => Str::of($expression->toString())->trim('{}'), ); @@ -151,7 +150,7 @@ public function toString(): string ) ->map(static fn($element) => $element->toString()); - return $this->string = Str::of(',') + return Str::of(',') ->join($expressions) ->prepend('{') ->append('}') diff --git a/src/Expression/Level4/Fragment.php b/src/Expression/Level4/Fragment.php index f8cdc22..62655c6 100644 --- a/src/Expression/Level4/Fragment.php +++ b/src/Expression/Level4/Fragment.php @@ -17,6 +17,9 @@ Str, }; +/** + * @psalm-immutable + */ final class Fragment implements Expression { private Expression $expression; @@ -28,6 +31,9 @@ public function __construct(Name $name) ->withExpression(Level2\Reserved::class); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if ($string->matches('~^\{#[a-zA-Z0-9_]+\}$~')) { @@ -51,6 +57,9 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } + /** + * @psalm-pure + */ public static function limit(Name $name, int $limit): self { if ($limit < 0) { @@ -65,15 +74,9 @@ public static function limit(Name $name, int $limit): self return $self; } - public function add(Str $pattern): Composite - { - return Composite::removeLead( - ',', - $this, - self::of($pattern->prepend('{#')->append('}')), - ); - } - + /** + * @psalm-pure + */ public static function explode(Name $name): self { $self = new self($name); @@ -84,6 +87,15 @@ public static function explode(Name $name): self return $self; } + public function add(Str $pattern): Composite + { + return Composite::removeLead( + ',', + $this, + self::of($pattern->prepend('{#')->append('}')), + ); + } + public function regex(): string { return $this->expression->regex(); diff --git a/src/Expression/Level4/Label.php b/src/Expression/Level4/Label.php index 6c36208..3a1a501 100644 --- a/src/Expression/Level4/Label.php +++ b/src/Expression/Level4/Label.php @@ -16,6 +16,9 @@ Str, }; +/** + * @psalm-immutable + */ final class Label implements Expression { private Expression $expression; @@ -25,6 +28,9 @@ public function __construct(Name $name) $this->expression = (new Level4($name))->withLead('.'); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if ($string->matches('~^\{\.[a-zA-Z0-9_]+\}$~')) { @@ -48,6 +54,9 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } + /** + * @psalm-pure + */ public static function limit(Name $name, int $limit): self { if ($limit < 0) { @@ -60,6 +69,9 @@ public static function limit(Name $name, int $limit): self return $self; } + /** + * @psalm-pure + */ public static function explode(Name $name): self { $self = new self($name); diff --git a/src/Expression/Level4/Parameters.php b/src/Expression/Level4/Parameters.php index 111bb68..ad092f0 100644 --- a/src/Expression/Level4/Parameters.php +++ b/src/Expression/Level4/Parameters.php @@ -19,14 +19,15 @@ Sequence, }; +/** + * @psalm-immutable + */ final class Parameters implements Expression { private Name $name; private ?int $limit = null; private bool $explode = false; private Expression $expression; - private ?string $regex = null; - private ?string $string = null; public function __construct(Name $name) { @@ -34,6 +35,9 @@ public function __construct(Name $name) $this->expression = new Level1($name); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if ($string->matches('~^\{;[a-zA-Z0-9_]+\}$~')) { @@ -57,6 +61,9 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } + /** + * @psalm-pure + */ public static function limit(Name $name, int $limit): self { if ($limit < 0) { @@ -69,6 +76,9 @@ public static function limit(Name $name, int $limit): self return $self; } + /** + * @psalm-pure + */ public static function explode(Name $name): self { $self = new self($name); @@ -120,10 +130,6 @@ public function expand(Map $variables): string public function regex(): string { - if (\is_string($this->regex)) { - return $this->regex; - } - if ($this->explode) { throw new ExplodeExpressionCantBeMatched; } @@ -138,7 +144,7 @@ public function regex(): string $regex = $this->expression->regex(); } - return $this->regex = \sprintf( + return \sprintf( '\;%s=%s', $this->name->toString(), $regex, @@ -147,19 +153,15 @@ public function regex(): string public function toString(): string { - if (\is_string($this->string)) { - return $this->string; - } - if ($this->mustLimit()) { - return $this->string = "{;{$this->name->toString()}:{$this->limit}}"; + return "{;{$this->name->toString()}:{$this->limit}}"; } if ($this->explode) { - return $this->string = "{;{$this->name->toString()}*}"; + return "{;{$this->name->toString()}*}"; } - return $this->string = "{;{$this->name->toString()}}"; + return "{;{$this->name->toString()}}"; } private function mustLimit(): bool diff --git a/src/Expression/Level4/Path.php b/src/Expression/Level4/Path.php index 170668d..584fb41 100644 --- a/src/Expression/Level4/Path.php +++ b/src/Expression/Level4/Path.php @@ -16,6 +16,9 @@ Str, }; +/** + * @psalm-immutable + */ final class Path implements Expression { private Expression $expression; @@ -25,6 +28,9 @@ public function __construct(Name $name) $this->expression = (new Level4($name))->withLead('/'); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if ($string->matches('~^\{/[a-zA-Z0-9_]+\}$~')) { @@ -48,6 +54,9 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } + /** + * @psalm-pure + */ public static function limit(Name $name, int $limit): self { if ($limit < 0) { @@ -60,6 +69,9 @@ public static function limit(Name $name, int $limit): self return $self; } + /** + * @psalm-pure + */ public static function explode(Name $name): self { $self = new self($name); diff --git a/src/Expression/Level4/Query.php b/src/Expression/Level4/Query.php index 53c5491..46cc9a4 100644 --- a/src/Expression/Level4/Query.php +++ b/src/Expression/Level4/Query.php @@ -19,14 +19,15 @@ Sequence, }; +/** + * @psalm-immutable + */ final class Query implements Expression { private Name $name; private ?int $limit = null; private bool $explode = false; private Expression $expression; - private ?string $regex = null; - private ?string $string = null; public function __construct(Name $name) { @@ -34,6 +35,9 @@ public function __construct(Name $name) $this->expression = new Level1($name); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if ($string->matches('~^\{\?[a-zA-Z0-9_]+\}$~')) { @@ -57,6 +61,9 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } + /** + * @psalm-pure + */ public static function limit(Name $name, int $limit): self { if ($limit < 0) { @@ -69,6 +76,9 @@ public static function limit(Name $name, int $limit): self return $self; } + /** + * @psalm-pure + */ public static function explode(Name $name): self { $self = new self($name); @@ -120,10 +130,6 @@ public function expand(Map $variables): string public function regex(): string { - if (\is_string($this->regex)) { - return $this->regex; - } - if ($this->explode) { throw new ExplodeExpressionCantBeMatched; } @@ -138,7 +144,7 @@ public function regex(): string $regex = $this->expression->regex(); } - return $this->regex = \sprintf( + return \sprintf( '\?%s=%s', $this->name->toString(), $regex, @@ -147,19 +153,15 @@ public function regex(): string public function toString(): string { - if (\is_string($this->string)) { - return $this->string; - } - if ($this->mustLimit()) { - return $this->string = "{?{$this->name->toString()}:{$this->limit}}"; + return "{?{$this->name->toString()}:{$this->limit}}"; } if ($this->explode) { - return $this->string = "{?{$this->name->toString()}*}"; + return "{?{$this->name->toString()}*}"; } - return $this->string = "{?{$this->name->toString()}}"; + return "{?{$this->name->toString()}}"; } private function mustLimit(): bool diff --git a/src/Expression/Level4/QueryContinuation.php b/src/Expression/Level4/QueryContinuation.php index 7a276ed..ae5eae9 100644 --- a/src/Expression/Level4/QueryContinuation.php +++ b/src/Expression/Level4/QueryContinuation.php @@ -19,14 +19,15 @@ Sequence, }; +/** + * @psalm-immutable + */ final class QueryContinuation implements Expression { private Name $name; private ?int $limit = null; private bool $explode = false; private Expression $expression; - private ?string $regex = null; - private ?string $string = null; public function __construct(Name $name) { @@ -34,6 +35,9 @@ public function __construct(Name $name) $this->expression = new Level1($name); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if ($string->matches('~^\{\&[a-zA-Z0-9_]+\}$~')) { @@ -57,6 +61,9 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } + /** + * @psalm-pure + */ public static function limit(Name $name, int $limit): self { if ($limit < 0) { @@ -69,6 +76,9 @@ public static function limit(Name $name, int $limit): self return $self; } + /** + * @psalm-pure + */ public static function explode(Name $name): self { $self = new self($name); @@ -120,10 +130,6 @@ public function expand(Map $variables): string public function regex(): string { - if (\is_string($this->regex)) { - return $this->regex; - } - if ($this->explode) { throw new ExplodeExpressionCantBeMatched; } @@ -138,7 +144,7 @@ public function regex(): string $regex = $this->expression->regex(); } - return $this->regex = \sprintf( + return \sprintf( '\&%s=%s', $this->name->toString(), $regex, @@ -147,19 +153,15 @@ public function regex(): string public function toString(): string { - if (\is_string($this->string)) { - return $this->string; - } - if ($this->mustLimit()) { - return $this->string = "{&{$this->name->toString()}:{$this->limit}}"; + return "{&{$this->name->toString()}:{$this->limit}}"; } if ($this->explode) { - return $this->string = "{&{$this->name->toString()}*}"; + return "{&{$this->name->toString()}*}"; } - return $this->string = "{&{$this->name->toString()}}"; + return "{&{$this->name->toString()}}"; } private function mustLimit(): bool diff --git a/src/Expression/Level4/Reserved.php b/src/Expression/Level4/Reserved.php index 216bf6d..7881d84 100644 --- a/src/Expression/Level4/Reserved.php +++ b/src/Expression/Level4/Reserved.php @@ -17,14 +17,15 @@ Str, }; +/** + * @psalm-immutable + */ final class Reserved implements Expression { private Name $name; private ?int $limit = null; private bool $explode = false; private Expression $expression; - private ?string $regex = null; - private ?string $string = null; public function __construct(Name $name) { @@ -34,6 +35,9 @@ public function __construct(Name $name) ); } + /** + * @psalm-pure + */ public static function of(Str $string): Expression { if ($string->matches('~^\{\+[a-zA-Z0-9_]+\}$~')) { @@ -57,6 +61,9 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } + /** + * @psalm-pure + */ public static function limit(Name $name, int $limit): self { if ($limit < 0) { @@ -72,6 +79,9 @@ public static function limit(Name $name, int $limit): self return $self; } + /** + * @psalm-pure + */ public static function explode(Name $name): self { $self = new self($name); @@ -99,35 +109,27 @@ public function expand(Map $variables): string public function regex(): string { - if (\is_string($this->regex)) { - return $this->regex; - } - if ($this->explode) { throw new ExplodeExpressionCantBeMatched; } if (\is_int($this->limit)) { - return $this->regex = "(?<{$this->name->toString()}>[a-zA-Z0-9\%:/\?#\[\]@!\$&'\(\)\*\+,;=\-\.\_\~]{{$this->limit}})"; + return "(?<{$this->name->toString()}>[a-zA-Z0-9\%:/\?#\[\]@!\$&'\(\)\*\+,;=\-\.\_\~]{{$this->limit}})"; } - return $this->regex = $this->expression->regex(); + return $this->expression->regex(); } public function toString(): string { - if (\is_string($this->string)) { - return $this->string; - } - if (\is_int($this->limit)) { - return $this->string = "{+{$this->name->toString()}:{$this->limit}}"; + return "{+{$this->name->toString()}:{$this->limit}}"; } if ($this->explode) { - return $this->string = "{+{$this->name->toString()}*}"; + return "{+{$this->name->toString()}*}"; } - return $this->string = "{+{$this->name->toString()}}"; + return "{+{$this->name->toString()}}"; } } diff --git a/src/Expression/Name.php b/src/Expression/Name.php index cc906ff..dcdfe46 100644 --- a/src/Expression/Name.php +++ b/src/Expression/Name.php @@ -6,6 +6,9 @@ use Innmind\UrlTemplate\Exception\DomainException; use Innmind\Immutable\Str; +/** + * @psalm-immutable + */ final class Name { private string $value; diff --git a/src/Expressions.php b/src/Expressions.php index 13f556d..44dad23 100644 --- a/src/Expressions.php +++ b/src/Expressions.php @@ -9,11 +9,14 @@ Str, }; +/** + * @psalm-immutable + */ final class Expressions { - /** @var list */ - private static ?array $expressions = null; - + /** + * @psalm-pure + */ public static function of(Str $string): Expression { foreach (self::expressions() as $expression) { @@ -29,11 +32,13 @@ public static function of(Str $string): Expression } /** - * @return list + * @psalm-pure + * + * @return list> */ private static function expressions(): array { - return self::$expressions ?? self::$expressions = [ + return [ Expression\Level4::class, Expression\Level4\Reserved::class, Expression\Level4\Fragment::class, diff --git a/src/Template.php b/src/Template.php index 5b15859..2da3875 100644 --- a/src/Template.php +++ b/src/Template.php @@ -15,6 +15,9 @@ Str, }; +/** + * @psalm-immutable + */ final class Template { private Str $template; @@ -33,6 +36,9 @@ private function __construct(string $template) ->map(Expressions::of(...)); } + /** + * @psalm-pure + */ public static function of(string $template): self { return new self($template); diff --git a/src/UrlEncode.php b/src/UrlEncode.php index 699ccf6..25739fb 100644 --- a/src/UrlEncode.php +++ b/src/UrlEncode.php @@ -5,6 +5,9 @@ use Innmind\Immutable\Str; +/** + * @psalm-immutable + */ final class UrlEncode { private Str $safeCharacters; @@ -42,6 +45,9 @@ public function __invoke(string $string): string return \rawurlencode($string->toString()); } + /** + * @psalm-pure + */ public static function allowReservedCharacters(): self { $self = new self; From d2002452037bd32a18b49d5d4a0decbd863768d2 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 30 Jul 2022 11:48:14 +0200 Subject: [PATCH 08/39] remove unnecessary psalm suppressions --- src/Expression/Level4.php | 1 - src/Expression/Level4/Parameters.php | 2 -- src/Expression/Level4/Query.php | 2 -- src/Expression/Level4/QueryContinuation.php | 2 -- 4 files changed, 7 deletions(-) diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index ff4b607..7f75ccb 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -255,7 +255,6 @@ function($variableToExpand) use ($variables): string { $variableToExpand = $value; } - /** @psalm-suppress MixedArgument */ $variables = ($variables)($this->name->toString(), $variableToExpand); $value = $this->expression->expand($variables); diff --git a/src/Expression/Level4/Parameters.php b/src/Expression/Level4/Parameters.php index ad092f0..c8aa71a 100644 --- a/src/Expression/Level4/Parameters.php +++ b/src/Expression/Level4/Parameters.php @@ -195,7 +195,6 @@ static function($variableToExpand): Sequence { function($variableToExpand) use ($variables): string { // here we use the level1 expression to transform the variable to // be expanded to its string representation - /** @psalm-suppress MixedArgument */ $variables = ($variables)($this->name->toString(), $variableToExpand); return $this->expression->expand($variables); @@ -225,7 +224,6 @@ function($variableToExpand) use ($variables): string { $variableToExpand = $value; } - /** @psalm-suppress MixedArgument */ $variables = ($variables)($name->toString(), $variableToExpand); return (new Level3\Parameters($name))->expand($variables); diff --git a/src/Expression/Level4/Query.php b/src/Expression/Level4/Query.php index 46cc9a4..3c40245 100644 --- a/src/Expression/Level4/Query.php +++ b/src/Expression/Level4/Query.php @@ -195,7 +195,6 @@ static function($variableToExpand): Sequence { // here we use the level1 expression to transform the variable to // be expanded to its string representation - /** @psalm-suppress MixedArgument */ $variables = ($variables)($this->name->toString(), $variableToExpand); return $this->expression->expand($variables); @@ -223,7 +222,6 @@ private function explodeList(Map $variables, array $variablesToExpand): string $variableToExpand = $value; } - /** @psalm-suppress MixedArgument */ $variables = ($variables)($name->toString(), $variableToExpand); $value = (new Level3\Query($name))->expand($variables); diff --git a/src/Expression/Level4/QueryContinuation.php b/src/Expression/Level4/QueryContinuation.php index ae5eae9..1a78161 100644 --- a/src/Expression/Level4/QueryContinuation.php +++ b/src/Expression/Level4/QueryContinuation.php @@ -194,7 +194,6 @@ static function($variableToExpand): Sequence { $expanded = $flattenedVariables->map(function($variableToExpand) use ($variables): string { // here we use the level1 expression to transform the variable to // be expanded to its string representation - /** @psalm-suppress MixedArgument */ $variables = ($variables)($this->name->toString(), $variableToExpand); return $this->expression->expand($variables); @@ -222,7 +221,6 @@ private function explodeList(Map $variables, array $variablesToExpand): string $variableToExpand = $value; } - /** @psalm-suppress MixedArgument */ $variables = ($variables)($name->toString(), $variableToExpand); return (new Level3\QueryContinuation($name))->expand($variables); From c3ec00a0fb87b65838b26a7a0cf5dcc38272207a Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 30 Jul 2022 12:17:33 +0200 Subject: [PATCH 09/39] reduce the usage of variadics --- src/Expression/Level3.php | 18 +++++++++--------- src/Expression/Level3/Fragment.php | 18 +++++++++--------- src/Expression/Level3/Label.php | 18 +++++++++--------- src/Expression/Level3/NamedValues.php | 13 +++++++------ src/Expression/Level3/Parameters.php | 18 +++++++++--------- src/Expression/Level3/Path.php | 18 +++++++++--------- src/Expression/Level3/Query.php | 18 +++++++++--------- src/Expression/Level3/QueryContinuation.php | 18 +++++++++--------- src/Expression/Level3/Reserved.php | 18 +++++++++--------- src/Expression/Level4/Parameters.php | 2 +- src/Expression/Level4/Query.php | 2 +- src/Expression/Level4/QueryContinuation.php | 2 +- tests/Expression/Level3/FragmentTest.php | 9 +++++---- tests/Expression/Level3/LabelTest.php | 9 +++++---- tests/Expression/Level3/ParametersTest.php | 9 +++++---- tests/Expression/Level3/PathTest.php | 9 +++++---- .../Level3/QueryContinuationTest.php | 9 +++++---- tests/Expression/Level3/QueryTest.php | 9 +++++---- tests/Expression/Level3/ReservedTest.php | 9 +++++---- tests/Expression/Level3Test.php | 9 +++++---- 20 files changed, 122 insertions(+), 113 deletions(-) diff --git a/src/Expression/Level3.php b/src/Expression/Level3.php index bedeaef..ad2aa15 100644 --- a/src/Expression/Level3.php +++ b/src/Expression/Level3.php @@ -24,11 +24,11 @@ final class Level3 implements Expression private Sequence $expressions; /** - * @no-named-arguments + * @param Sequence $names */ - public function __construct(Name ...$names) + public function __construct(Sequence $names) { - $this->names = Sequence::of(...$names); + $this->names = $names; $this->expressions = $this->names->map( static fn(Name $name) => new Level1($name), ); @@ -43,12 +43,12 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - $names = $string - ->trim('{}') - ->split(',') - ->map(static fn($name) => new Name($name->toString())); - - return new self(...$names->toList()); + return new self( + $string + ->trim('{}') + ->split(',') + ->map(static fn($name) => new Name($name->toString())), + ); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Fragment.php b/src/Expression/Level3/Fragment.php index d97a852..3053a1f 100644 --- a/src/Expression/Level3/Fragment.php +++ b/src/Expression/Level3/Fragment.php @@ -26,11 +26,11 @@ final class Fragment implements Expression private Sequence $expressions; /** - * @no-named-arguments + * @param Sequence $names */ - public function __construct(Name ...$names) + public function __construct(Sequence $names) { - $this->names = Sequence::of(...$names); + $this->names = $names; /** @var Sequence */ $this->expressions = $this->names->map( static fn(Name $name) => new Level2\Reserved($name), @@ -46,12 +46,12 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - $names = $string - ->trim('{#}') - ->split(',') - ->map(static fn($name) => new Name($name->toString())); - - return new self(...$names->toList()); + return new self( + $string + ->trim('{#}') + ->split(',') + ->map(static fn($name) => new Name($name->toString())), + ); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Label.php b/src/Expression/Level3/Label.php index bc5ed8b..104c071 100644 --- a/src/Expression/Level3/Label.php +++ b/src/Expression/Level3/Label.php @@ -26,11 +26,11 @@ final class Label implements Expression private Sequence $expressions; /** - * @no-named-arguments + * @param Sequence $names */ - public function __construct(Name ...$names) + public function __construct(Sequence $names) { - $this->names = Sequence::of(...$names); + $this->names = $names; /** @var Sequence */ $this->expressions = $this->names->map( static fn(Name $name) => new Level1($name), @@ -46,12 +46,12 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - $names = $string - ->trim('{.}') - ->split(',') - ->map(static fn($name) => new Name($name->toString())); - - return new self(...$names->toList()); + return new self( + $string + ->trim('{.}') + ->split(',') + ->map(static fn($name) => new Name($name->toString())), + ); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/NamedValues.php b/src/Expression/Level3/NamedValues.php index a4b1467..9b45ac2 100644 --- a/src/Expression/Level3/NamedValues.php +++ b/src/Expression/Level3/NamedValues.php @@ -28,13 +28,13 @@ final class NamedValues implements Expression private bool $keyOnlyWhenEmpty = false; /** - * @no-named-arguments + * @param Sequence $names */ - public function __construct(string $lead, string $separator, Name ...$names) + public function __construct(string $lead, string $separator, Sequence $names) { $this->lead = $lead; $this->separator = $separator; - $this->names = Sequence::of(...$names); + $this->names = $names; /** @var Map */ $this->expressions = Map::of( ...$this @@ -56,12 +56,13 @@ public static function of(Str $string): Expression } /** - * @no-named-arguments * @psalm-pure + * + * @param Sequence $names */ - public static function keyOnlyWhenEmpty(string $lead, string $separator, Name ...$names): self + public static function keyOnlyWhenEmpty(string $lead, string $separator, Sequence $names): self { - $self = new self($lead, $separator, ...$names); + $self = new self($lead, $separator, $names); $self->keyOnlyWhenEmpty = true; return $self; diff --git a/src/Expression/Level3/Parameters.php b/src/Expression/Level3/Parameters.php index 28d4eac..75cd072 100644 --- a/src/Expression/Level3/Parameters.php +++ b/src/Expression/Level3/Parameters.php @@ -22,11 +22,11 @@ final class Parameters implements Expression private Expression $expression; /** - * @no-named-arguments + * @param Sequence $names */ - public function __construct(Name ...$names) + public function __construct(Sequence $names) { - $this->expression = NamedValues::keyOnlyWhenEmpty(';', ';', ...$names); + $this->expression = NamedValues::keyOnlyWhenEmpty(';', ';', $names); } /** @@ -38,12 +38,12 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - $names = $string - ->trim('{;}') - ->split(',') - ->map(static fn($name) => new Name($name->toString())); - - return new self(...$names->toList()); + return new self( + $string + ->trim('{;}') + ->split(',') + ->map(static fn($name) => new Name($name->toString())), + ); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Path.php b/src/Expression/Level3/Path.php index aaab953..605e5ab 100644 --- a/src/Expression/Level3/Path.php +++ b/src/Expression/Level3/Path.php @@ -26,11 +26,11 @@ final class Path implements Expression private Sequence $expressions; /** - * @no-named-arguments + * @param Sequence $names */ - public function __construct(Name ...$names) + public function __construct(Sequence $names) { - $this->names = Sequence::of(...$names); + $this->names = $names; /** @var Sequence */ $this->expressions = $this->names->map( static fn(Name $name) => new Level1($name), @@ -46,12 +46,12 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - $names = $string - ->trim('{/}') - ->split(',') - ->map(static fn($name) => new Name($name->toString())); - - return new self(...$names->toList()); + return new self( + $string + ->trim('{/}') + ->split(',') + ->map(static fn($name) => new Name($name->toString())), + ); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Query.php b/src/Expression/Level3/Query.php index 2b0abda..bf11e83 100644 --- a/src/Expression/Level3/Query.php +++ b/src/Expression/Level3/Query.php @@ -22,11 +22,11 @@ final class Query implements Expression private Expression $expression; /** - * @no-named-arguments + * @param Sequence $names */ - public function __construct(Name ...$names) + public function __construct(Sequence $names) { - $this->expression = new NamedValues('?', '&', ...$names); + $this->expression = new NamedValues('?', '&', $names); } /** @@ -38,12 +38,12 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - $names = $string - ->trim('{?}') - ->split(',') - ->map(static fn($name) => new Name($name->toString())); - - return new self(...$names->toList()); + return new self( + $string + ->trim('{?}') + ->split(',') + ->map(static fn($name) => new Name($name->toString())), + ); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/QueryContinuation.php b/src/Expression/Level3/QueryContinuation.php index 550628d..ae19dd6 100644 --- a/src/Expression/Level3/QueryContinuation.php +++ b/src/Expression/Level3/QueryContinuation.php @@ -22,11 +22,11 @@ final class QueryContinuation implements Expression private Expression $expression; /** - * @no-named-arguments + * @param Sequence $names */ - public function __construct(Name ...$names) + public function __construct(Sequence $names) { - $this->expression = new NamedValues('&', '&', ...$names); + $this->expression = new NamedValues('&', '&', $names); } /** @@ -38,12 +38,12 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - $names = $string - ->trim('{&}') - ->split(',') - ->map(static fn($name) => new Name($name->toString())); - - return new self(...$names->toList()); + return new self( + $string + ->trim('{&}') + ->split(',') + ->map(static fn($name) => new Name($name->toString())), + ); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Reserved.php b/src/Expression/Level3/Reserved.php index 9d19a4a..d301b76 100644 --- a/src/Expression/Level3/Reserved.php +++ b/src/Expression/Level3/Reserved.php @@ -26,11 +26,11 @@ final class Reserved implements Expression private Sequence $expressions; /** - * @no-named-arguments + * @param Sequence $names */ - public function __construct(Name ...$names) + public function __construct(Sequence $names) { - $this->names = Sequence::of(...$names); + $this->names = $names; /** @var Sequence */ $this->expressions = $this->names->map( static fn(Name $name) => new Level2\Reserved($name), @@ -46,12 +46,12 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - $names = $string - ->trim('{+}') - ->split(',') - ->map(static fn($name) => new Name($name->toString())); - - return new self(...$names->toList()); + return new self( + $string + ->trim('{+}') + ->split(',') + ->map(static fn($name) => new Name($name->toString())), + ); } public function expand(Map $variables): string diff --git a/src/Expression/Level4/Parameters.php b/src/Expression/Level4/Parameters.php index c8aa71a..c3dde80 100644 --- a/src/Expression/Level4/Parameters.php +++ b/src/Expression/Level4/Parameters.php @@ -226,7 +226,7 @@ function($variableToExpand) use ($variables): string { $variables = ($variables)($name->toString(), $variableToExpand); - return (new Level3\Parameters($name))->expand($variables); + return (new Level3\Parameters(Sequence::of($name)))->expand($variables); }, ); diff --git a/src/Expression/Level4/Query.php b/src/Expression/Level4/Query.php index 3c40245..19e47e1 100644 --- a/src/Expression/Level4/Query.php +++ b/src/Expression/Level4/Query.php @@ -224,7 +224,7 @@ private function explodeList(Map $variables, array $variablesToExpand): string $variables = ($variables)($name->toString(), $variableToExpand); - $value = (new Level3\Query($name))->expand($variables); + $value = (new Level3\Query(Sequence::of($name)))->expand($variables); // the substring is here to remove the '?' as it should be a '&' // done below in the join diff --git a/src/Expression/Level4/QueryContinuation.php b/src/Expression/Level4/QueryContinuation.php index 1a78161..a4c3ed7 100644 --- a/src/Expression/Level4/QueryContinuation.php +++ b/src/Expression/Level4/QueryContinuation.php @@ -223,7 +223,7 @@ private function explodeList(Map $variables, array $variablesToExpand): string $variables = ($variables)($name->toString(), $variableToExpand); - return (new Level3\QueryContinuation($name))->expand($variables); + return (new Level3\QueryContinuation(Sequence::of($name)))->expand($variables); }); return Str::of('')->join($expanded)->toString(); diff --git a/tests/Expression/Level3/FragmentTest.php b/tests/Expression/Level3/FragmentTest.php index e51ca6e..b6982de 100644 --- a/tests/Expression/Level3/FragmentTest.php +++ b/tests/Expression/Level3/FragmentTest.php @@ -12,6 +12,7 @@ use Innmind\Immutable\{ Map, Str, + Sequence, }; use PHPUnit\Framework\TestCase; @@ -21,7 +22,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Fragment(new Name('foo'), new Name('bar')), + new Fragment(Sequence::of(new Name('foo'), new Name('bar'))), ); } @@ -29,7 +30,7 @@ public function testStringCast() { $this->assertSame( '{#foo,bar}', - (new Fragment(new Name('foo'), new Name('bar')))->toString(), + (new Fragment(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), ); } @@ -45,11 +46,11 @@ public function testExpand() $this->assertSame( '#1024,Hello%20World!,768', - (new Fragment(new Name('x'), new Name('hello'), new Name('y')))->expand($variables), + (new Fragment(Sequence::of(new Name('x'), new Name('hello'), new Name('y'))))->expand($variables), ); $this->assertSame( '#/foo/bar,1024', - (new Fragment(new Name('path'), new Name('x')))->expand($variables), + (new Fragment(Sequence::of(new Name('path'), new Name('x'))))->expand($variables), ); } diff --git a/tests/Expression/Level3/LabelTest.php b/tests/Expression/Level3/LabelTest.php index f4c279c..8e19de6 100644 --- a/tests/Expression/Level3/LabelTest.php +++ b/tests/Expression/Level3/LabelTest.php @@ -12,6 +12,7 @@ use Innmind\Immutable\{ Map, Str, + Sequence, }; use PHPUnit\Framework\TestCase; @@ -21,7 +22,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Label(new Name('foo'), new Name('bar')), + new Label(Sequence::of(new Name('foo'), new Name('bar'))), ); } @@ -29,7 +30,7 @@ public function testStringCast() { $this->assertSame( '{.foo,bar}', - (new Label(new Name('foo'), new Name('bar')))->toString(), + (new Label(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), ); } @@ -45,11 +46,11 @@ public function testExpand() $this->assertSame( '.1024.768', - (new Label(new Name('x'), new Name('y')))->expand($variables), + (new Label(Sequence::of(new Name('x'), new Name('y'))))->expand($variables), ); $this->assertSame( '.value', - (new Label(new Name('var')))->expand($variables), + (new Label(Sequence::of(new Name('var'))))->expand($variables), ); } diff --git a/tests/Expression/Level3/ParametersTest.php b/tests/Expression/Level3/ParametersTest.php index cbc7309..80e48b0 100644 --- a/tests/Expression/Level3/ParametersTest.php +++ b/tests/Expression/Level3/ParametersTest.php @@ -12,6 +12,7 @@ use Innmind\Immutable\{ Map, Str, + Sequence, }; use PHPUnit\Framework\TestCase; @@ -21,7 +22,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Parameters(new Name('foo'), new Name('bar')), + new Parameters(Sequence::of(new Name('foo'), new Name('bar'))), ); } @@ -29,7 +30,7 @@ public function testStringCast() { $this->assertSame( '{;foo,bar}', - (new Parameters(new Name('foo'), new Name('bar')))->toString(), + (new Parameters(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), ); } @@ -45,11 +46,11 @@ public function testExpand() $this->assertSame( ';x=1024;y=768', - (new Parameters(new Name('x'), new Name('y')))->expand($variables), + (new Parameters(Sequence::of(new Name('x'), new Name('y'))))->expand($variables), ); $this->assertSame( ';x=1024;y=768;empty', - (new Parameters(new Name('x'), new Name('y'), new Name('empty')))->expand($variables), + (new Parameters(Sequence::of(new Name('x'), new Name('y'), new Name('empty'))))->expand($variables), ); } diff --git a/tests/Expression/Level3/PathTest.php b/tests/Expression/Level3/PathTest.php index 070bb7d..6e78920 100644 --- a/tests/Expression/Level3/PathTest.php +++ b/tests/Expression/Level3/PathTest.php @@ -12,6 +12,7 @@ use Innmind\Immutable\{ Map, Str, + Sequence, }; use PHPUnit\Framework\TestCase; @@ -21,7 +22,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Path(new Name('foo'), new Name('bar')), + new Path(Sequence::of(new Name('foo'), new Name('bar'))), ); } @@ -29,7 +30,7 @@ public function testStringCast() { $this->assertSame( '{/foo,bar}', - (new Path(new Name('foo'), new Name('bar')))->toString(), + (new Path(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), ); } @@ -45,11 +46,11 @@ public function testExpand() $this->assertSame( '/value', - (new Path(new Name('var')))->expand($variables), + (new Path(Sequence::of(new Name('var'))))->expand($variables), ); $this->assertSame( '/value/1024', - (new Path(new Name('var'), new Name('x')))->expand($variables), + (new Path(Sequence::of(new Name('var'), new Name('x'))))->expand($variables), ); } diff --git a/tests/Expression/Level3/QueryContinuationTest.php b/tests/Expression/Level3/QueryContinuationTest.php index 3c67e83..e3c5e2d 100644 --- a/tests/Expression/Level3/QueryContinuationTest.php +++ b/tests/Expression/Level3/QueryContinuationTest.php @@ -12,6 +12,7 @@ use Innmind\Immutable\{ Map, Str, + Sequence, }; use PHPUnit\Framework\TestCase; @@ -21,7 +22,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new QueryContinuation(new Name('foo'), new Name('bar')), + new QueryContinuation(Sequence::of(new Name('foo'), new Name('bar'))), ); } @@ -29,7 +30,7 @@ public function testStringCast() { $this->assertSame( '{&foo,bar}', - (new QueryContinuation(new Name('foo'), new Name('bar')))->toString(), + (new QueryContinuation(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), ); } @@ -45,11 +46,11 @@ public function testExpand() $this->assertSame( '&x=1024&y=768', - (new QueryContinuation(new Name('x'), new Name('y')))->expand($variables), + (new QueryContinuation(Sequence::of(new Name('x'), new Name('y'))))->expand($variables), ); $this->assertSame( '&x=1024&y=768&empty=', - (new QueryContinuation(new Name('x'), new Name('y'), new Name('empty')))->expand($variables), + (new QueryContinuation(Sequence::of(new Name('x'), new Name('y'), new Name('empty'))))->expand($variables), ); } diff --git a/tests/Expression/Level3/QueryTest.php b/tests/Expression/Level3/QueryTest.php index d5f29eb..471cfbc 100644 --- a/tests/Expression/Level3/QueryTest.php +++ b/tests/Expression/Level3/QueryTest.php @@ -12,6 +12,7 @@ use Innmind\Immutable\{ Map, Str, + Sequence, }; use PHPUnit\Framework\TestCase; @@ -21,7 +22,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Query(new Name('foo'), new Name('bar')), + new Query(Sequence::of(new Name('foo'), new Name('bar'))), ); } @@ -29,7 +30,7 @@ public function testStringCast() { $this->assertSame( '{?foo,bar}', - (new Query(new Name('foo'), new Name('bar')))->toString(), + (new Query(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), ); } @@ -45,11 +46,11 @@ public function testExpand() $this->assertSame( '?x=1024&y=768', - (new Query(new Name('x'), new Name('y')))->expand($variables), + (new Query(Sequence::of(new Name('x'), new Name('y'))))->expand($variables), ); $this->assertSame( '?x=1024&y=768&empty=', - (new Query(new Name('x'), new Name('y'), new Name('empty')))->expand($variables), + (new Query(Sequence::of(new Name('x'), new Name('y'), new Name('empty'))))->expand($variables), ); } diff --git a/tests/Expression/Level3/ReservedTest.php b/tests/Expression/Level3/ReservedTest.php index 37ab006..70f1b63 100644 --- a/tests/Expression/Level3/ReservedTest.php +++ b/tests/Expression/Level3/ReservedTest.php @@ -12,6 +12,7 @@ use Innmind\Immutable\{ Map, Str, + Sequence, }; use PHPUnit\Framework\TestCase; @@ -21,7 +22,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Reserved(new Name('foo'), new Name('bar')), + new Reserved(Sequence::of(new Name('foo'), new Name('bar'))), ); } @@ -29,7 +30,7 @@ public function testStringCast() { $this->assertSame( '{+foo,bar}', - (new Reserved(new Name('foo'), new Name('bar')))->toString(), + (new Reserved(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), ); } @@ -45,11 +46,11 @@ public function testExpand() $this->assertSame( '1024,Hello%20World!,768', - (new Reserved(new Name('x'), new Name('hello'), new Name('y')))->expand($variables), + (new Reserved(Sequence::of(new Name('x'), new Name('hello'), new Name('y'))))->expand($variables), ); $this->assertSame( '/foo/bar,1024', - (new Reserved(new Name('path'), new Name('x')))->expand($variables), + (new Reserved(Sequence::of(new Name('path'), new Name('x'))))->expand($variables), ); } diff --git a/tests/Expression/Level3Test.php b/tests/Expression/Level3Test.php index d319f0a..88b5e39 100644 --- a/tests/Expression/Level3Test.php +++ b/tests/Expression/Level3Test.php @@ -12,6 +12,7 @@ use Innmind\Immutable\{ Map, Str, + Sequence, }; use PHPUnit\Framework\TestCase; @@ -21,7 +22,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Level3(new Name('foo'), new Name('bar')), + new Level3(Sequence::of(new Name('foo'), new Name('bar'))), ); } @@ -29,7 +30,7 @@ public function testStringCast() { $this->assertSame( '{foo,bar}', - (new Level3(new Name('foo'), new Name('bar')))->toString(), + (new Level3(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), ); } @@ -45,11 +46,11 @@ public function testExpand() $this->assertSame( '1024,768', - (new Level3(new Name('x'), new Name('y')))->expand($variables), + (new Level3(Sequence::of(new Name('x'), new Name('y'))))->expand($variables), ); $this->assertSame( '1024,Hello%20World%21,768', - (new Level3(new Name('x'), new Name('hello'), new Name('y')))->expand($variables), + (new Level3(Sequence::of(new Name('x'), new Name('hello'), new Name('y'))))->expand($variables), ); } From e9e304658dd050ca4b43e1b66f5646e744b2bedc Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 30 Jul 2022 14:09:06 +0200 Subject: [PATCH 10/39] simplify the encoding of strings --- src/UrlEncode.php | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/UrlEncode.php b/src/UrlEncode.php index 25739fb..1230f4d 100644 --- a/src/UrlEncode.php +++ b/src/UrlEncode.php @@ -3,7 +3,10 @@ namespace Innmind\UrlTemplate; -use Innmind\Immutable\Str; +use Innmind\Immutable\{ + Str, + Monoid\Concat, +}; /** * @psalm-immutable @@ -23,26 +26,13 @@ public function __invoke(string $string): string return \rawurlencode($string); } - $string = Str::of($string); - - if ($string->length() > 1) { - $characters = $string - ->split() - ->map(fn($character) => Str::of($this($character->toString()))) - ->map(static fn($character) => $character->toString()); - - return Str::of('')->join($characters)->toString(); - } - - if ($string->empty()) { - return ''; - } - - if ($this->safeCharacters->contains($string->toString())) { - return $string->toString(); - } - - return \rawurlencode($string->toString()); + return Str::of($string) + ->split() + ->map(static fn($char) => $char->toString()) + ->map($this->encode(...)) + ->map(Str::of(...)) + ->fold(new Concat) + ->toString(); } /** @@ -55,4 +45,12 @@ public static function allowReservedCharacters(): self return $self; } + + private function encode(string $char): string + { + return match ($this->safeCharacters->contains($char)) { + true => $char, + false => \rawurlencode($char), + }; + } } From 07214e508334ce6aff32d44764c265010c5fd6aa Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 30 Jul 2022 14:13:50 +0200 Subject: [PATCH 11/39] use sequence to be more explicit --- src/UrlEncode.php | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/UrlEncode.php b/src/UrlEncode.php index 1230f4d..8f7944d 100644 --- a/src/UrlEncode.php +++ b/src/UrlEncode.php @@ -5,6 +5,7 @@ use Innmind\Immutable\{ Str, + Sequence, Monoid\Concat, }; @@ -13,11 +14,12 @@ */ final class UrlEncode { - private Str $safeCharacters; + /** @var Sequence */ + private Sequence $safeCharacters; public function __construct() { - $this->safeCharacters = Str::of(''); + $this->safeCharacters = Sequence::strings(); } public function __invoke(string $string): string @@ -41,7 +43,26 @@ public function __invoke(string $string): string public static function allowReservedCharacters(): self { $self = new self; - $self->safeCharacters = Str::of(':/?#[]@!$&\'()*+,;='); + $self->safeCharacters = Sequence::strings( + ':', + '/', + '?', + '#', + '[', + ']', + '@', + '!', + '$', + '&', + "'", + '(', + ')', + '*', + '+', + ',', + ';', + '=', + ); return $self; } From c3e99ad1ddbccf36587cc2a761dc9bf31ea095a3 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 30 Jul 2022 16:05:42 +0200 Subject: [PATCH 12/39] make constructors private --- src/Expression/Level1.php | 12 ++++++-- src/Expression/Level2/Fragment.php | 4 +-- src/Expression/Level2/Reserved.php | 12 ++++++-- src/Expression/Level3.php | 9 +++--- src/Expression/Level3/Fragment.php | 11 ++++--- src/Expression/Level3/Label.php | 11 ++++--- src/Expression/Level3/NamedValues.php | 4 +-- src/Expression/Level3/Parameters.php | 13 ++++++-- src/Expression/Level3/Path.php | 11 ++++--- src/Expression/Level3/Query.php | 15 ++++++++-- src/Expression/Level3/QueryContinuation.php | 12 ++++++-- src/Expression/Level3/Reserved.php | 11 ++++--- src/Expression/Level4.php | 30 +++++++++++-------- src/Expression/Level4/Fragment.php | 16 +++++----- src/Expression/Level4/Label.php | 10 +++---- src/Expression/Level4/Parameters.php | 14 ++++----- src/Expression/Level4/Path.php | 10 +++---- src/Expression/Level4/Query.php | 14 ++++----- src/Expression/Level4/QueryContinuation.php | 14 ++++----- src/Expression/Level4/Reserved.php | 16 +++++----- src/Expression/Name.php | 12 ++++++-- tests/Expression/Level1Test.php | 9 +++--- tests/Expression/Level2/FragmentTest.php | 9 +++--- tests/Expression/Level2/ReservedTest.php | 9 +++--- tests/Expression/Level3/FragmentTest.php | 14 ++++----- tests/Expression/Level3/LabelTest.php | 14 ++++----- tests/Expression/Level3/ParametersTest.php | 10 +++---- tests/Expression/Level3/PathTest.php | 14 ++++----- .../Level3/QueryContinuationTest.php | 14 ++++----- tests/Expression/Level3/QueryTest.php | 14 ++++----- tests/Expression/Level3/ReservedTest.php | 14 ++++----- tests/Expression/Level3Test.php | 10 +++---- tests/Expression/Level4/CompositeTest.php | 17 +++++------ tests/Expression/Level4/FragmentTest.php | 25 ++++++++-------- tests/Expression/Level4/LabelTest.php | 25 ++++++++-------- tests/Expression/Level4/ParametersTest.php | 25 ++++++++-------- tests/Expression/Level4/PathTest.php | 23 +++++++------- .../Level4/QueryContinuationTest.php | 25 ++++++++-------- tests/Expression/Level4/QueryTest.php | 25 ++++++++-------- tests/Expression/Level4/ReservedTest.php | 25 ++++++++-------- tests/Expression/Level4Test.php | 29 +++++++++--------- tests/Expression/NameTest.php | 4 +-- 42 files changed, 317 insertions(+), 298 deletions(-) diff --git a/src/Expression/Level1.php b/src/Expression/Level1.php index 42bee39..7aad040 100644 --- a/src/Expression/Level1.php +++ b/src/Expression/Level1.php @@ -22,7 +22,7 @@ final class Level1 implements Expression private Name $name; private UrlEncode $encode; - public function __construct(Name $name) + private function __construct(Name $name) { $this->name = $name; $this->encode = new UrlEncode; @@ -37,7 +37,15 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - return new self(new Name($string->trim('{}')->toString())); + return new self(Name::of($string->trim('{}')->toString())); + } + + /** + * @psalm-pure + */ + public static function named(Name $name): self + { + return new self($name); } public function expand(Map $variables): string diff --git a/src/Expression/Level2/Fragment.php b/src/Expression/Level2/Fragment.php index e7f5093..06eb835 100644 --- a/src/Expression/Level2/Fragment.php +++ b/src/Expression/Level2/Fragment.php @@ -23,7 +23,7 @@ final class Fragment implements Expression private Name $name; private UrlEncode $encode; - public function __construct(Name $name) + private function __construct(Name $name) { $this->name = $name; $this->encode = UrlEncode::allowReservedCharacters(); @@ -38,7 +38,7 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - return new self(new Name($string->trim('{#}')->toString())); + return new self(Name::of($string->trim('{#}')->toString())); } public function expand(Map $variables): string diff --git a/src/Expression/Level2/Reserved.php b/src/Expression/Level2/Reserved.php index f4c5228..38ddb6d 100644 --- a/src/Expression/Level2/Reserved.php +++ b/src/Expression/Level2/Reserved.php @@ -23,7 +23,7 @@ final class Reserved implements Expression private Name $name; private UrlEncode $encode; - public function __construct(Name $name) + private function __construct(Name $name) { $this->name = $name; $this->encode = UrlEncode::allowReservedCharacters(); @@ -38,7 +38,15 @@ public static function of(Str $string): Expression throw new DomainException($string->toString()); } - return new self(new Name($string->trim('{+}')->toString())); + return new self(Name::of($string->trim('{+}')->toString())); + } + + /** + * @psalm-pure + */ + public static function named(Name $name): self + { + return new self($name); } public function expand(Map $variables): string diff --git a/src/Expression/Level3.php b/src/Expression/Level3.php index ad2aa15..6940029 100644 --- a/src/Expression/Level3.php +++ b/src/Expression/Level3.php @@ -26,12 +26,10 @@ final class Level3 implements Expression /** * @param Sequence $names */ - public function __construct(Sequence $names) + private function __construct(Sequence $names) { $this->names = $names; - $this->expressions = $this->names->map( - static fn(Name $name) => new Level1($name), - ); + $this->expressions = $this->names->map(Level1::named(...)); } /** @@ -47,7 +45,8 @@ public static function of(Str $string): Expression $string ->trim('{}') ->split(',') - ->map(static fn($name) => new Name($name->toString())), + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), ); } diff --git a/src/Expression/Level3/Fragment.php b/src/Expression/Level3/Fragment.php index 3053a1f..a9f692e 100644 --- a/src/Expression/Level3/Fragment.php +++ b/src/Expression/Level3/Fragment.php @@ -28,13 +28,11 @@ final class Fragment implements Expression /** * @param Sequence $names */ - public function __construct(Sequence $names) + private function __construct(Sequence $names) { $this->names = $names; /** @var Sequence */ - $this->expressions = $this->names->map( - static fn(Name $name) => new Level2\Reserved($name), - ); + $this->expressions = $this->names->map(Level2\Reserved::named(...)); } /** @@ -42,7 +40,7 @@ public function __construct(Sequence $names) */ public static function of(Str $string): Expression { - if (!$string->matches('~^\{#[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { + if (!$string->matches('~^\{#[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) { throw new DomainException($string->toString()); } @@ -50,7 +48,8 @@ public static function of(Str $string): Expression $string ->trim('{#}') ->split(',') - ->map(static fn($name) => new Name($name->toString())), + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), ); } diff --git a/src/Expression/Level3/Label.php b/src/Expression/Level3/Label.php index 104c071..2ee461c 100644 --- a/src/Expression/Level3/Label.php +++ b/src/Expression/Level3/Label.php @@ -28,13 +28,11 @@ final class Label implements Expression /** * @param Sequence $names */ - public function __construct(Sequence $names) + private function __construct(Sequence $names) { $this->names = $names; /** @var Sequence */ - $this->expressions = $this->names->map( - static fn(Name $name) => new Level1($name), - ); + $this->expressions = $this->names->map(Level1::named(...)); } /** @@ -42,7 +40,7 @@ public function __construct(Sequence $names) */ public static function of(Str $string): Expression { - if (!$string->matches('~^\{\.[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { + if (!$string->matches('~^\{\.[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) { throw new DomainException($string->toString()); } @@ -50,7 +48,8 @@ public static function of(Str $string): Expression $string ->trim('{.}') ->split(',') - ->map(static fn($name) => new Name($name->toString())), + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), ); } diff --git a/src/Expression/Level3/NamedValues.php b/src/Expression/Level3/NamedValues.php index 9b45ac2..09cd13c 100644 --- a/src/Expression/Level3/NamedValues.php +++ b/src/Expression/Level3/NamedValues.php @@ -41,7 +41,7 @@ public function __construct(string $lead, string $separator, Sequence $names) ->names ->map(static fn($name) => [ $name->toString(), - new Level1($name), + Level1::named($name), ]) ->toList(), ); @@ -98,7 +98,7 @@ public function regex(): string '%s=%s%s', $name->toString(), $this->keyOnlyWhenEmpty ? '?' : '', - (new Level1($name))->regex(), + Level1::named($name)->regex(), ), )) ->prepend('\\'.$this->lead) diff --git a/src/Expression/Level3/Parameters.php b/src/Expression/Level3/Parameters.php index 75cd072..a3ba6f7 100644 --- a/src/Expression/Level3/Parameters.php +++ b/src/Expression/Level3/Parameters.php @@ -24,7 +24,7 @@ final class Parameters implements Expression /** * @param Sequence $names */ - public function __construct(Sequence $names) + private function __construct(Sequence $names) { $this->expression = NamedValues::keyOnlyWhenEmpty(';', ';', $names); } @@ -42,10 +42,19 @@ public static function of(Str $string): Expression $string ->trim('{;}') ->split(',') - ->map(static fn($name) => new Name($name->toString())), + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), ); } + /** + * @psalm-pure + */ + public static function named(Name $name): self + { + return new self(Sequence::of($name)); + } + public function expand(Map $variables): string { return $this->expression->expand($variables); diff --git a/src/Expression/Level3/Path.php b/src/Expression/Level3/Path.php index 605e5ab..94efc8f 100644 --- a/src/Expression/Level3/Path.php +++ b/src/Expression/Level3/Path.php @@ -28,13 +28,11 @@ final class Path implements Expression /** * @param Sequence $names */ - public function __construct(Sequence $names) + private function __construct(Sequence $names) { $this->names = $names; /** @var Sequence */ - $this->expressions = $this->names->map( - static fn(Name $name) => new Level1($name), - ); + $this->expressions = $this->names->map(Level1::named(...)); } /** @@ -42,7 +40,7 @@ public function __construct(Sequence $names) */ public static function of(Str $string): Expression { - if (!$string->matches('~^\{/[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { + if (!$string->matches('~^\{/[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) { throw new DomainException($string->toString()); } @@ -50,7 +48,8 @@ public static function of(Str $string): Expression $string ->trim('{/}') ->split(',') - ->map(static fn($name) => new Name($name->toString())), + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), ); } diff --git a/src/Expression/Level3/Query.php b/src/Expression/Level3/Query.php index bf11e83..c901142 100644 --- a/src/Expression/Level3/Query.php +++ b/src/Expression/Level3/Query.php @@ -24,7 +24,7 @@ final class Query implements Expression /** * @param Sequence $names */ - public function __construct(Sequence $names) + private function __construct(Sequence $names) { $this->expression = new NamedValues('?', '&', $names); } @@ -34,7 +34,7 @@ public function __construct(Sequence $names) */ public static function of(Str $string): Expression { - if (!$string->matches('~^\{\?[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { + if (!$string->matches('~^\{\?[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) { throw new DomainException($string->toString()); } @@ -42,10 +42,19 @@ public static function of(Str $string): Expression $string ->trim('{?}') ->split(',') - ->map(static fn($name) => new Name($name->toString())), + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), ); } + /** + * @psalm-pure + */ + public static function named(Name $name): self + { + return new self(Sequence::of($name)); + } + public function expand(Map $variables): string { return $this->expression->expand($variables); diff --git a/src/Expression/Level3/QueryContinuation.php b/src/Expression/Level3/QueryContinuation.php index ae19dd6..cd98837 100644 --- a/src/Expression/Level3/QueryContinuation.php +++ b/src/Expression/Level3/QueryContinuation.php @@ -24,7 +24,7 @@ final class QueryContinuation implements Expression /** * @param Sequence $names */ - public function __construct(Sequence $names) + private function __construct(Sequence $names) { $this->expression = new NamedValues('&', '&', $names); } @@ -34,7 +34,7 @@ public function __construct(Sequence $names) */ public static function of(Str $string): Expression { - if (!$string->matches('~^\{\&[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { + if (!$string->matches('~^\{\&[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) { throw new DomainException($string->toString()); } @@ -42,10 +42,16 @@ public static function of(Str $string): Expression $string ->trim('{&}') ->split(',') - ->map(static fn($name) => new Name($name->toString())), + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), ); } + public static function named(Name $name): self + { + return new self(Sequence::of($name)); + } + public function expand(Map $variables): string { return $this->expression->expand($variables); diff --git a/src/Expression/Level3/Reserved.php b/src/Expression/Level3/Reserved.php index d301b76..c790cf0 100644 --- a/src/Expression/Level3/Reserved.php +++ b/src/Expression/Level3/Reserved.php @@ -28,13 +28,11 @@ final class Reserved implements Expression /** * @param Sequence $names */ - public function __construct(Sequence $names) + private function __construct(Sequence $names) { $this->names = $names; /** @var Sequence */ - $this->expressions = $this->names->map( - static fn(Name $name) => new Level2\Reserved($name), - ); + $this->expressions = $this->names->map(Level2\Reserved::named(...)); } /** @@ -42,7 +40,7 @@ public function __construct(Sequence $names) */ public static function of(Str $string): Expression { - if (!$string->matches('~^\{\+[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { + if (!$string->matches('~^\{\+[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) { throw new DomainException($string->toString()); } @@ -50,7 +48,8 @@ public static function of(Str $string): Expression $string ->trim('{+}') ->split(',') - ->map(static fn($name) => new Name($name->toString())), + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), ); } diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index 7f75ccb..20163e7 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -28,10 +28,10 @@ final class Level4 implements Expression private string $lead = ''; private string $separator = ','; - public function __construct(Name $name) + private function __construct(Name $name) { $this->name = $name; - $this->expression = new Level1($name); + $this->expression = Level1::named($name); } /** @@ -40,11 +40,11 @@ public function __construct(Name $name) public static function of(Str $string): Expression { if ($string->matches('~^\{[a-zA-Z0-9_]+\}$~')) { - return new self(new Name($string->trim('{}')->toString())); + return new self(Name::of($string->trim('{}')->toString())); } if ($string->matches('~^\{[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(new Name($string->trim('{*}')->toString())); + return self::explode(Name::of($string->trim('{*}')->toString())); } if ($string->matches('~^\{[a-zA-Z0-9_]+:\d+\}$~')) { @@ -52,7 +52,7 @@ public static function of(Str $string): Expression [$name, $limit] = $string->split(':')->toList(); return self::limit( - new Name($name->toString()), + Name::of($name->toString()), (int) $limit->toString(), ); } @@ -86,6 +86,14 @@ public static function explode(Name $name): self return $self; } + /** + * @psalm-pure + */ + public static function named(Name $name): self + { + return new self($name); + } + public function add(Str $pattern): Composite { return new Composite( @@ -115,16 +123,12 @@ public function withSeparator(string $separator): self * Not ideal technic but didn't find a better to reduce duplicated code * @internal * - * @param class-string $expression + * @param pure-callable(Name): Expression $expression */ - public function withExpression(string $expression): self + public function withExpression(callable $expression): self { - if (!\is_a($expression, Expression::class, true)) { - throw new DomainException($expression); - } - $self = clone $this; - $self->expression = new $expression($self->name); + $self->expression = $expression($self->name); return $self; } @@ -261,7 +265,7 @@ function($variableToExpand) use ($variables): string { if (isset($name)) { /** @psalm-suppress MixedArgument */ - $name = new Name($name); + $name = Name::of($name); $value = \sprintf( '%s=%s', $name->toString(), diff --git a/src/Expression/Level4/Fragment.php b/src/Expression/Level4/Fragment.php index 62655c6..a70e527 100644 --- a/src/Expression/Level4/Fragment.php +++ b/src/Expression/Level4/Fragment.php @@ -24,11 +24,11 @@ final class Fragment implements Expression { private Expression $expression; - public function __construct(Name $name) + private function __construct(Name $name) { - $this->expression = (new Level4($name)) + $this->expression = Level4::named($name) ->withLead('#') - ->withExpression(Level2\Reserved::class); + ->withExpression(Level2\Reserved::named(...)); } /** @@ -37,11 +37,11 @@ public function __construct(Name $name) public static function of(Str $string): Expression { if ($string->matches('~^\{#[a-zA-Z0-9_]+\}$~')) { - return new self(new Name($string->trim('{#}')->toString())); + return new self(Name::of($string->trim('{#}')->toString())); } if ($string->matches('~^\{#[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(new Name($string->trim('{#*}')->toString())); + return self::explode(Name::of($string->trim('{#*}')->toString())); } if ($string->matches('~^\{#[a-zA-Z0-9_]+:\d+\}$~')) { @@ -49,7 +49,7 @@ public static function of(Str $string): Expression [$name, $limit] = $string->split(':')->toList(); return self::limit( - new Name($name->toString()), + Name::of($name->toString()), (int) $limit->toString(), ); } @@ -69,7 +69,7 @@ public static function limit(Name $name, int $limit): self $self = new self($name); $self->expression = Level4::limit($name, $limit) ->withLead('#') - ->withExpression(Level2\Reserved::class); + ->withExpression(Level2\Reserved::named(...)); return $self; } @@ -82,7 +82,7 @@ public static function explode(Name $name): self $self = new self($name); $self->expression = Level4::explode($name) ->withLead('#') - ->withExpression(Level2\Reserved::class); + ->withExpression(Level2\Reserved::named(...)); return $self; } diff --git a/src/Expression/Level4/Label.php b/src/Expression/Level4/Label.php index 3a1a501..ff4207c 100644 --- a/src/Expression/Level4/Label.php +++ b/src/Expression/Level4/Label.php @@ -23,9 +23,9 @@ final class Label implements Expression { private Expression $expression; - public function __construct(Name $name) + private function __construct(Name $name) { - $this->expression = (new Level4($name))->withLead('.'); + $this->expression = Level4::named($name)->withLead('.'); } /** @@ -34,11 +34,11 @@ public function __construct(Name $name) public static function of(Str $string): Expression { if ($string->matches('~^\{\.[a-zA-Z0-9_]+\}$~')) { - return new self(new Name($string->trim('{.}')->toString())); + return new self(Name::of($string->trim('{.}')->toString())); } if ($string->matches('~^\{\.[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(new Name($string->trim('{.*}')->toString())); + return self::explode(Name::of($string->trim('{.*}')->toString())); } if ($string->matches('~^\{\.[a-zA-Z0-9_]+:\d+\}$~')) { @@ -46,7 +46,7 @@ public static function of(Str $string): Expression [$name, $limit] = $string->split(':')->toList(); return self::limit( - new Name($name->toString()), + Name::of($name->toString()), (int) $limit->toString(), ); } diff --git a/src/Expression/Level4/Parameters.php b/src/Expression/Level4/Parameters.php index c3dde80..21c29a3 100644 --- a/src/Expression/Level4/Parameters.php +++ b/src/Expression/Level4/Parameters.php @@ -29,10 +29,10 @@ final class Parameters implements Expression private bool $explode = false; private Expression $expression; - public function __construct(Name $name) + private function __construct(Name $name) { $this->name = $name; - $this->expression = new Level1($name); + $this->expression = Level1::named($name); } /** @@ -41,11 +41,11 @@ public function __construct(Name $name) public static function of(Str $string): Expression { if ($string->matches('~^\{;[a-zA-Z0-9_]+\}$~')) { - return new self(new Name($string->trim('{;}')->toString())); + return new self(Name::of($string->trim('{;}')->toString())); } if ($string->matches('~^\{;[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(new Name($string->trim('{;*}')->toString())); + return self::explode(Name::of($string->trim('{;*}')->toString())); } if ($string->matches('~^\{;[a-zA-Z0-9_]+:\d+\}$~')) { @@ -53,7 +53,7 @@ public static function of(Str $string): Expression [$name, $limit] = $string->split(':')->toList(); return self::limit( - new Name($name->toString()), + Name::of($name->toString()), (int) $limit->toString(), ); } @@ -220,13 +220,13 @@ function($variableToExpand) use ($variables): string { if (\is_array($variableToExpand)) { [$name, $value] = $variableToExpand; - $name = new Name($name); + $name = Name::of($name); $variableToExpand = $value; } $variables = ($variables)($name->toString(), $variableToExpand); - return (new Level3\Parameters(Sequence::of($name)))->expand($variables); + return Level3\Parameters::named($name)->expand($variables); }, ); diff --git a/src/Expression/Level4/Path.php b/src/Expression/Level4/Path.php index 584fb41..edcb5d3 100644 --- a/src/Expression/Level4/Path.php +++ b/src/Expression/Level4/Path.php @@ -23,9 +23,9 @@ final class Path implements Expression { private Expression $expression; - public function __construct(Name $name) + private function __construct(Name $name) { - $this->expression = (new Level4($name))->withLead('/'); + $this->expression = Level4::named($name)->withLead('/'); } /** @@ -34,11 +34,11 @@ public function __construct(Name $name) public static function of(Str $string): Expression { if ($string->matches('~^\{/[a-zA-Z0-9_]+\}$~')) { - return new self(new Name($string->trim('{/}')->toString())); + return new self(Name::of($string->trim('{/}')->toString())); } if ($string->matches('~^\{/[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(new Name($string->trim('{/*}')->toString())); + return self::explode(Name::of($string->trim('{/*}')->toString())); } if ($string->matches('~^\{/[a-zA-Z0-9_]+:\d+\}$~')) { @@ -46,7 +46,7 @@ public static function of(Str $string): Expression [$name, $limit] = $string->split(':')->toList(); return self::limit( - new Name($name->toString()), + Name::of($name->toString()), (int) $limit->toString(), ); } diff --git a/src/Expression/Level4/Query.php b/src/Expression/Level4/Query.php index 19e47e1..681c0f1 100644 --- a/src/Expression/Level4/Query.php +++ b/src/Expression/Level4/Query.php @@ -29,10 +29,10 @@ final class Query implements Expression private bool $explode = false; private Expression $expression; - public function __construct(Name $name) + private function __construct(Name $name) { $this->name = $name; - $this->expression = new Level1($name); + $this->expression = Level1::named($name); } /** @@ -41,11 +41,11 @@ public function __construct(Name $name) public static function of(Str $string): Expression { if ($string->matches('~^\{\?[a-zA-Z0-9_]+\}$~')) { - return new self(new Name($string->trim('{?}')->toString())); + return new self(Name::of($string->trim('{?}')->toString())); } if ($string->matches('~^\{\?[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(new Name($string->trim('{?*}')->toString())); + return self::explode(Name::of($string->trim('{?*}')->toString())); } if ($string->matches('~^\{\?[a-zA-Z0-9_]+:\d+\}$~')) { @@ -53,7 +53,7 @@ public static function of(Str $string): Expression [$name, $limit] = $string->split(':')->toList(); return self::limit( - new Name($name->toString()), + Name::of($name->toString()), (int) $limit->toString(), ); } @@ -218,13 +218,13 @@ private function explodeList(Map $variables, array $variablesToExpand): string if (\is_array($variableToExpand)) { [$name, $value] = $variableToExpand; - $name = new Name($name); + $name = Name::of($name); $variableToExpand = $value; } $variables = ($variables)($name->toString(), $variableToExpand); - $value = (new Level3\Query(Sequence::of($name)))->expand($variables); + $value = Level3\Query::named($name)->expand($variables); // the substring is here to remove the '?' as it should be a '&' // done below in the join diff --git a/src/Expression/Level4/QueryContinuation.php b/src/Expression/Level4/QueryContinuation.php index a4c3ed7..6871eea 100644 --- a/src/Expression/Level4/QueryContinuation.php +++ b/src/Expression/Level4/QueryContinuation.php @@ -29,10 +29,10 @@ final class QueryContinuation implements Expression private bool $explode = false; private Expression $expression; - public function __construct(Name $name) + private function __construct(Name $name) { $this->name = $name; - $this->expression = new Level1($name); + $this->expression = Level1::named($name); } /** @@ -41,11 +41,11 @@ public function __construct(Name $name) public static function of(Str $string): Expression { if ($string->matches('~^\{\&[a-zA-Z0-9_]+\}$~')) { - return new self(new Name($string->trim('{&}')->toString())); + return new self(Name::of($string->trim('{&}')->toString())); } if ($string->matches('~^\{\&[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(new Name($string->trim('{&*}')->toString())); + return self::explode(Name::of($string->trim('{&*}')->toString())); } if ($string->matches('~^\{\&[a-zA-Z0-9_]+:\d+\}$~')) { @@ -53,7 +53,7 @@ public static function of(Str $string): Expression [$name, $limit] = $string->split(':')->toList(); return self::limit( - new Name($name->toString()), + Name::of($name->toString()), (int) $limit->toString(), ); } @@ -217,13 +217,13 @@ private function explodeList(Map $variables, array $variablesToExpand): string if (\is_array($variableToExpand)) { [$name, $value] = $variableToExpand; - $name = new Name($name); + $name = Name::of($name); $variableToExpand = $value; } $variables = ($variables)($name->toString(), $variableToExpand); - return (new Level3\QueryContinuation(Sequence::of($name)))->expand($variables); + return Level3\QueryContinuation::named($name)->expand($variables); }); return Str::of('')->join($expanded)->toString(); diff --git a/src/Expression/Level4/Reserved.php b/src/Expression/Level4/Reserved.php index 7881d84..4218015 100644 --- a/src/Expression/Level4/Reserved.php +++ b/src/Expression/Level4/Reserved.php @@ -27,11 +27,11 @@ final class Reserved implements Expression private bool $explode = false; private Expression $expression; - public function __construct(Name $name) + private function __construct(Name $name) { $this->name = $name; - $this->expression = (new Level4($name))->withExpression( - Level2\Reserved::class, + $this->expression = Level4::named($name)->withExpression( + Level2\Reserved::named(...), ); } @@ -41,11 +41,11 @@ public function __construct(Name $name) public static function of(Str $string): Expression { if ($string->matches('~^\{\+[a-zA-Z0-9_]+\}$~')) { - return new self(new Name($string->trim('{+}')->toString())); + return new self(Name::of($string->trim('{+}')->toString())); } if ($string->matches('~^\{\+[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(new Name($string->trim('{+*}')->toString())); + return self::explode(Name::of($string->trim('{+*}')->toString())); } if ($string->matches('~^\{\+[a-zA-Z0-9_]+:\d+\}$~')) { @@ -53,7 +53,7 @@ public static function of(Str $string): Expression [$name, $limit] = $string->split(':')->toList(); return self::limit( - new Name($name->toString()), + Name::of($name->toString()), (int) $limit->toString(), ); } @@ -73,7 +73,7 @@ public static function limit(Name $name, int $limit): self $self = new self($name); $self->limit = $limit; $self->expression = Level4::limit($name, $limit)->withExpression( - Level2\Reserved::class, + Level2\Reserved::named(...), ); return $self; @@ -87,7 +87,7 @@ public static function explode(Name $name): self $self = new self($name); $self->explode = true; $self->expression = Level4::explode($name)->withExpression( - Level2\Reserved::class, + Level2\Reserved::named(...), ); return $self; diff --git a/src/Expression/Name.php b/src/Expression/Name.php index dcdfe46..ee49b0c 100644 --- a/src/Expression/Name.php +++ b/src/Expression/Name.php @@ -13,13 +13,21 @@ final class Name { private string $value; - public function __construct(string $value) + private function __construct(string $value) + { + $this->value = $value; + } + + /** + * @psalm-pure + */ + public static function of(string $value): self { if (!Str::of($value)->matches('~[a-zA-Z0-9_]+~')) { throw new DomainException($value); } - $this->value = $value; + return new self($value); } public function toString(): string diff --git a/tests/Expression/Level1Test.php b/tests/Expression/Level1Test.php index 2005883..2605bcf 100644 --- a/tests/Expression/Level1Test.php +++ b/tests/Expression/Level1Test.php @@ -5,7 +5,6 @@ use Innmind\UrlTemplate\{ Expression\Level1, - Expression\Name, Expression, Exception\DomainException, Exception\OnlyScalarCanBeExpandedForExpression, @@ -22,18 +21,18 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Level1(new Name('foo')), + Level1::of(Str::of('{foo}')), ); } public function testStringCast() { - $this->assertSame('{foo}', (new Level1(new Name('foo')))->toString()); + $this->assertSame('{foo}', Level1::of(Str::of('{foo}'))->toString()); } public function testExpand() { - $expression = new Level1(new Name('foo')); + $expression = Level1::of(Str::of('{foo}')); $this->assertSame('value', $expression->expand( Map::of(['foo', 'value']), @@ -73,7 +72,7 @@ public function testRegex() public function testThrowWhenTryingToExpandWithAnArray() { - $expression = new Level1(new Name('foo')); + $expression = Level1::of(Str::of('{foo}')); $this->expectException(OnlyScalarCanBeExpandedForExpression::class); $this->expectExceptionMessage('foo'); diff --git a/tests/Expression/Level2/FragmentTest.php b/tests/Expression/Level2/FragmentTest.php index c571ba4..ab553c3 100644 --- a/tests/Expression/Level2/FragmentTest.php +++ b/tests/Expression/Level2/FragmentTest.php @@ -5,7 +5,6 @@ use Innmind\UrlTemplate\{ Expression\Level2\Fragment, - Expression\Name, Expression, Exception\DomainException, Exception\OnlyScalarCanBeExpandedForExpression, @@ -22,18 +21,18 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Fragment(new Name('foo')), + Fragment::of(Str::of('{#foo}')), ); } public function testStringCast() { - $this->assertSame('{#foo}', (new Fragment(new Name('foo')))->toString()); + $this->assertSame('{#foo}', Fragment::of(Str::of('{#foo}'))->toString()); } public function testExpand() { - $expression = new Fragment(new Name('foo')); + $expression = Fragment::of(Str::of('{#foo}')); $this->assertSame('#value', $expression->expand( Map::of(['foo', 'value']), @@ -76,7 +75,7 @@ public function testRegex() public function testThrowWhenTryingToExpandWithAnArray() { - $expression = new Fragment(new Name('foo')); + $expression = Fragment::of(Str::of('{#foo}')); $this->expectException(OnlyScalarCanBeExpandedForExpression::class); $this->expectExceptionMessage('foo'); diff --git a/tests/Expression/Level2/ReservedTest.php b/tests/Expression/Level2/ReservedTest.php index 1ac3523..2e76fb0 100644 --- a/tests/Expression/Level2/ReservedTest.php +++ b/tests/Expression/Level2/ReservedTest.php @@ -5,7 +5,6 @@ use Innmind\UrlTemplate\{ Expression\Level2\Reserved, - Expression\Name, Expression, Exception\DomainException, Exception\OnlyScalarCanBeExpandedForExpression, @@ -22,18 +21,18 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Reserved(new Name('foo')), + Reserved::of(Str::of('{+foo}')), ); } public function testStringCast() { - $this->assertSame('{+foo}', (new Reserved(new Name('foo')))->toString()); + $this->assertSame('{+foo}', Reserved::of(Str::of('{+foo}'))->toString()); } public function testExpand() { - $expression = new Reserved(new Name('foo')); + $expression = Reserved::of(Str::of('{+foo}')); $this->assertSame('value', $expression->expand( Map::of(['foo', 'value']), @@ -76,7 +75,7 @@ public function testRegex() public function testThrowWhenTryingToExpandWithAnArray() { - $expression = new Reserved(new Name('foo')); + $expression = Reserved::of(Str::of('{+foo}')); $this->expectException(OnlyScalarCanBeExpandedForExpression::class); $this->expectExceptionMessage('foo'); diff --git a/tests/Expression/Level3/FragmentTest.php b/tests/Expression/Level3/FragmentTest.php index b6982de..d960e10 100644 --- a/tests/Expression/Level3/FragmentTest.php +++ b/tests/Expression/Level3/FragmentTest.php @@ -5,14 +5,12 @@ use Innmind\UrlTemplate\{ Expression\Level3\Fragment, - Expression\Name, Expression, Exception\DomainException, }; use Innmind\Immutable\{ Map, Str, - Sequence, }; use PHPUnit\Framework\TestCase; @@ -22,7 +20,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Fragment(Sequence::of(new Name('foo'), new Name('bar'))), + Fragment::of(Str::of('{#foo,bar}')), ); } @@ -30,7 +28,7 @@ public function testStringCast() { $this->assertSame( '{#foo,bar}', - (new Fragment(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), + Fragment::of(Str::of('{#foo,bar}'))->toString(), ); } @@ -46,11 +44,11 @@ public function testExpand() $this->assertSame( '#1024,Hello%20World!,768', - (new Fragment(Sequence::of(new Name('x'), new Name('hello'), new Name('y'))))->expand($variables), + Fragment::of(Str::of('{#x,hello,y}'))->expand($variables), ); $this->assertSame( '#/foo/bar,1024', - (new Fragment(Sequence::of(new Name('path'), new Name('x'))))->expand($variables), + Fragment::of(Str::of('{#path,x}'))->expand($variables), ); } @@ -66,9 +64,9 @@ public function testOf() public function testThrowWhenInvalidPattern() { $this->expectException(DomainException::class); - $this->expectExceptionMessage('{#foo}'); + $this->expectExceptionMessage('{foo}'); - Fragment::of(Str::of('{#foo}')); + Fragment::of(Str::of('{foo}')); } public function testRegex() diff --git a/tests/Expression/Level3/LabelTest.php b/tests/Expression/Level3/LabelTest.php index 8e19de6..8acebef 100644 --- a/tests/Expression/Level3/LabelTest.php +++ b/tests/Expression/Level3/LabelTest.php @@ -5,14 +5,12 @@ use Innmind\UrlTemplate\{ Expression\Level3\Label, - Expression\Name, Expression, Exception\DomainException, }; use Innmind\Immutable\{ Map, Str, - Sequence, }; use PHPUnit\Framework\TestCase; @@ -22,7 +20,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Label(Sequence::of(new Name('foo'), new Name('bar'))), + Label::of(Str::of('{.foo,bar}')), ); } @@ -30,7 +28,7 @@ public function testStringCast() { $this->assertSame( '{.foo,bar}', - (new Label(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), + Label::of(Str::of('{.foo,bar}'))->toString(), ); } @@ -46,11 +44,11 @@ public function testExpand() $this->assertSame( '.1024.768', - (new Label(Sequence::of(new Name('x'), new Name('y'))))->expand($variables), + Label::of(Str::of('{.x,y}'))->expand($variables), ); $this->assertSame( '.value', - (new Label(Sequence::of(new Name('var'))))->expand($variables), + Label::of(Str::of('{.var}'))->expand($variables), ); } @@ -66,9 +64,9 @@ public function testOf() public function testThrowWhenInvalidPattern() { $this->expectException(DomainException::class); - $this->expectExceptionMessage('{.foo}'); + $this->expectExceptionMessage('{foo}'); - Label::of(Str::of('{.foo}')); + Label::of(Str::of('{foo}')); } public function testRegex() diff --git a/tests/Expression/Level3/ParametersTest.php b/tests/Expression/Level3/ParametersTest.php index 80e48b0..0edc133 100644 --- a/tests/Expression/Level3/ParametersTest.php +++ b/tests/Expression/Level3/ParametersTest.php @@ -5,14 +5,12 @@ use Innmind\UrlTemplate\{ Expression\Level3\Parameters, - Expression\Name, Expression, Exception\DomainException, }; use Innmind\Immutable\{ Map, Str, - Sequence, }; use PHPUnit\Framework\TestCase; @@ -22,7 +20,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Parameters(Sequence::of(new Name('foo'), new Name('bar'))), + Parameters::of(Str::of('{;foo,bar}')), ); } @@ -30,7 +28,7 @@ public function testStringCast() { $this->assertSame( '{;foo,bar}', - (new Parameters(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), + Parameters::of(Str::of('{;foo,bar}'))->toString(), ); } @@ -46,11 +44,11 @@ public function testExpand() $this->assertSame( ';x=1024;y=768', - (new Parameters(Sequence::of(new Name('x'), new Name('y'))))->expand($variables), + Parameters::of(Str::of('{;x,y}'))->expand($variables), ); $this->assertSame( ';x=1024;y=768;empty', - (new Parameters(Sequence::of(new Name('x'), new Name('y'), new Name('empty'))))->expand($variables), + Parameters::of(Str::of('{;x,y,empty}'))->expand($variables), ); } diff --git a/tests/Expression/Level3/PathTest.php b/tests/Expression/Level3/PathTest.php index 6e78920..ee9bd64 100644 --- a/tests/Expression/Level3/PathTest.php +++ b/tests/Expression/Level3/PathTest.php @@ -5,14 +5,12 @@ use Innmind\UrlTemplate\{ Expression\Level3\Path, - Expression\Name, Expression, Exception\DomainException, }; use Innmind\Immutable\{ Map, Str, - Sequence, }; use PHPUnit\Framework\TestCase; @@ -22,7 +20,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Path(Sequence::of(new Name('foo'), new Name('bar'))), + Path::of(Str::of('{/foo,bar}')), ); } @@ -30,7 +28,7 @@ public function testStringCast() { $this->assertSame( '{/foo,bar}', - (new Path(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), + Path::of(Str::of('{/foo,bar}'))->toString(), ); } @@ -46,11 +44,11 @@ public function testExpand() $this->assertSame( '/value', - (new Path(Sequence::of(new Name('var'))))->expand($variables), + Path::of(Str::of('{/var}'))->expand($variables), ); $this->assertSame( '/value/1024', - (new Path(Sequence::of(new Name('var'), new Name('x'))))->expand($variables), + Path::of(Str::of('{/var,x}'))->expand($variables), ); } @@ -66,9 +64,9 @@ public function testOf() public function testThrowWhenInvalidPattern() { $this->expectException(DomainException::class); - $this->expectExceptionMessage('{/foo}'); + $this->expectExceptionMessage('{foo}'); - Path::of(Str::of('{/foo}')); + Path::of(Str::of('{foo}')); } public function testRegex() diff --git a/tests/Expression/Level3/QueryContinuationTest.php b/tests/Expression/Level3/QueryContinuationTest.php index e3c5e2d..dfc6796 100644 --- a/tests/Expression/Level3/QueryContinuationTest.php +++ b/tests/Expression/Level3/QueryContinuationTest.php @@ -5,14 +5,12 @@ use Innmind\UrlTemplate\{ Expression\Level3\QueryContinuation, - Expression\Name, Expression, Exception\DomainException, }; use Innmind\Immutable\{ Map, Str, - Sequence, }; use PHPUnit\Framework\TestCase; @@ -22,7 +20,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new QueryContinuation(Sequence::of(new Name('foo'), new Name('bar'))), + QueryContinuation::of(Str::of('{&foo,bar}')), ); } @@ -30,7 +28,7 @@ public function testStringCast() { $this->assertSame( '{&foo,bar}', - (new QueryContinuation(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), + QueryContinuation::of(Str::of('{&foo,bar}'))->toString(), ); } @@ -46,11 +44,11 @@ public function testExpand() $this->assertSame( '&x=1024&y=768', - (new QueryContinuation(Sequence::of(new Name('x'), new Name('y'))))->expand($variables), + QueryContinuation::of(Str::of('{&x,y}'))->expand($variables), ); $this->assertSame( '&x=1024&y=768&empty=', - (new QueryContinuation(Sequence::of(new Name('x'), new Name('y'), new Name('empty'))))->expand($variables), + QueryContinuation::of(Str::of('{&x,y,empty}'))->expand($variables), ); } @@ -66,9 +64,9 @@ public function testOf() public function testThrowWhenInvalidPattern() { $this->expectException(DomainException::class); - $this->expectExceptionMessage('{&foo}'); + $this->expectExceptionMessage('{foo}'); - QueryContinuation::of(Str::of('{&foo}')); + QueryContinuation::of(Str::of('{foo}')); } public function testRegex() diff --git a/tests/Expression/Level3/QueryTest.php b/tests/Expression/Level3/QueryTest.php index 471cfbc..8114082 100644 --- a/tests/Expression/Level3/QueryTest.php +++ b/tests/Expression/Level3/QueryTest.php @@ -5,14 +5,12 @@ use Innmind\UrlTemplate\{ Expression\Level3\Query, - Expression\Name, Expression, Exception\DomainException, }; use Innmind\Immutable\{ Map, Str, - Sequence, }; use PHPUnit\Framework\TestCase; @@ -22,7 +20,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Query(Sequence::of(new Name('foo'), new Name('bar'))), + Query::of(Str::of('{?foo,bar}')), ); } @@ -30,7 +28,7 @@ public function testStringCast() { $this->assertSame( '{?foo,bar}', - (new Query(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), + Query::of(Str::of('{?foo,bar}'))->toString(), ); } @@ -46,11 +44,11 @@ public function testExpand() $this->assertSame( '?x=1024&y=768', - (new Query(Sequence::of(new Name('x'), new Name('y'))))->expand($variables), + Query::of(Str::of('{?x,y}'))->expand($variables), ); $this->assertSame( '?x=1024&y=768&empty=', - (new Query(Sequence::of(new Name('x'), new Name('y'), new Name('empty'))))->expand($variables), + Query::of(Str::of('{?x,y,empty}'))->expand($variables), ); } @@ -66,9 +64,9 @@ public function testOf() public function testThrowWhenInvalidPattern() { $this->expectException(DomainException::class); - $this->expectExceptionMessage('{?foo}'); + $this->expectExceptionMessage('{foo}'); - Query::of(Str::of('{?foo}')); + Query::of(Str::of('{foo}')); } public function testRegex() diff --git a/tests/Expression/Level3/ReservedTest.php b/tests/Expression/Level3/ReservedTest.php index 70f1b63..a847269 100644 --- a/tests/Expression/Level3/ReservedTest.php +++ b/tests/Expression/Level3/ReservedTest.php @@ -5,14 +5,12 @@ use Innmind\UrlTemplate\{ Expression\Level3\Reserved, - Expression\Name, Expression, Exception\DomainException, }; use Innmind\Immutable\{ Map, Str, - Sequence, }; use PHPUnit\Framework\TestCase; @@ -22,7 +20,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Reserved(Sequence::of(new Name('foo'), new Name('bar'))), + Reserved::of(Str::of('{+foo,bar}')), ); } @@ -30,7 +28,7 @@ public function testStringCast() { $this->assertSame( '{+foo,bar}', - (new Reserved(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), + Reserved::of(Str::of('{+foo,bar}'))->toString(), ); } @@ -46,11 +44,11 @@ public function testExpand() $this->assertSame( '1024,Hello%20World!,768', - (new Reserved(Sequence::of(new Name('x'), new Name('hello'), new Name('y'))))->expand($variables), + Reserved::of(Str::of('{+x,hello,y}'))->expand($variables), ); $this->assertSame( '/foo/bar,1024', - (new Reserved(Sequence::of(new Name('path'), new Name('x'))))->expand($variables), + Reserved::of(Str::of('{+path,x}'))->expand($variables), ); } @@ -66,9 +64,9 @@ public function testOf() public function testThrowWhenInvalidPattern() { $this->expectException(DomainException::class); - $this->expectExceptionMessage('{+foo}'); + $this->expectExceptionMessage('{foo}'); - Reserved::of(Str::of('{+foo}')); + Reserved::of(Str::of('{foo}')); } public function testRegex() diff --git a/tests/Expression/Level3Test.php b/tests/Expression/Level3Test.php index 88b5e39..10bca08 100644 --- a/tests/Expression/Level3Test.php +++ b/tests/Expression/Level3Test.php @@ -5,14 +5,12 @@ use Innmind\UrlTemplate\{ Expression\Level3, - Expression\Name, Expression, Exception\DomainException, }; use Innmind\Immutable\{ Map, Str, - Sequence, }; use PHPUnit\Framework\TestCase; @@ -22,7 +20,7 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Level3(Sequence::of(new Name('foo'), new Name('bar'))), + Level3::of(Str::of('{foo,bar}')), ); } @@ -30,7 +28,7 @@ public function testStringCast() { $this->assertSame( '{foo,bar}', - (new Level3(Sequence::of(new Name('foo'), new Name('bar'))))->toString(), + Level3::of(Str::of('{foo,bar}'))->toString(), ); } @@ -46,11 +44,11 @@ public function testExpand() $this->assertSame( '1024,768', - (new Level3(Sequence::of(new Name('x'), new Name('y'))))->expand($variables), + Level3::of(Str::of('{x,y}'))->expand($variables), ); $this->assertSame( '1024,Hello%20World%21,768', - (new Level3(Sequence::of(new Name('x'), new Name('hello'), new Name('y'))))->expand($variables), + Level3::of(Str::of('{x,hello,y}'))->expand($variables), ); } diff --git a/tests/Expression/Level4/CompositeTest.php b/tests/Expression/Level4/CompositeTest.php index 16e34da..e742ed9 100644 --- a/tests/Expression/Level4/CompositeTest.php +++ b/tests/Expression/Level4/CompositeTest.php @@ -7,7 +7,6 @@ Expression\Level4\Composite, Expression\Level4\Path, Expression\Level4, - Expression\Name, Expression, Exception\DomainException, }; @@ -36,16 +35,16 @@ public function testStringCast() '{/var:1,var}', (new Composite( '/', - Path::limit(new Name('var'), 1), - new Level4(new Name('var')), + Path::of(Str::of('{/var:1}')), + Level4::of(Str::of('{var}')), ))->toString(), ); $this->assertSame( '{/list*,path:4}', (new Composite( '/', - Path::explode(new Name('list')), - Level4::limit(new Name('path'), 4), + Path::of(Str::of('{/list*}')), + Level4::of(Str::of('{path:4}')), ))->toString(), ); } @@ -63,16 +62,16 @@ public function testExpand() '/v/value', (new Composite( '/', - Path::limit(new Name('var'), 1), - new Level4(new Name('var')), + Path::of(Str::of('{/var:1}')), + Level4::of(Str::of('{var}')), ))->expand($variables), ); $this->assertSame( '/red/green/blue/%2Ffoo', (new Composite( '/', - Path::explode(new Name('list')), - Level4::limit(new Name('path'), 4), + Path::of(Str::of('{/list*}')), + Level4::of(Str::of('{path:4}')), ))->expand($variables), ); } diff --git a/tests/Expression/Level4/FragmentTest.php b/tests/Expression/Level4/FragmentTest.php index 2bd1365..833f564 100644 --- a/tests/Expression/Level4/FragmentTest.php +++ b/tests/Expression/Level4/FragmentTest.php @@ -5,7 +5,6 @@ use Innmind\UrlTemplate\{ Expression\Level4\Fragment, - Expression\Name, Expression, Exception\DomainException, Exception\LogicException, @@ -28,23 +27,23 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Fragment(new Name('foo')), + Fragment::of(Str::of('{#foo}')), ); $this->assertInstanceOf( Expression::class, - Fragment::explode(new Name('foo')), + Fragment::of(Str::of('{#foo*}')), ); $this->assertInstanceOf( Expression::class, - Fragment::limit(new Name('foo'), 42), + Fragment::of(Str::of('{#foo:42}')), ); } public function testStringCast() { - $this->assertSame('{#foo}', (new Fragment(new Name('foo')))->toString()); - $this->assertSame('{#foo*}', Fragment::explode(new Name('foo'))->toString()); - $this->assertSame('{#foo:42}', Fragment::limit(new Name('foo'), 42)->toString()); + $this->assertSame('{#foo}', Fragment::of(Str::of('{#foo}'))->toString()); + $this->assertSame('{#foo*}', Fragment::of(Str::of('{#foo*}'))->toString()); + $this->assertSame('{#foo:42}', Fragment::of(Str::of('{#foo:42}'))->toString()); } public function testThrowWhenNegativeLimit() @@ -54,7 +53,7 @@ public function testThrowWhenNegativeLimit() ->then(function(int $int): void { $this->expectException(DomainException::class); - Fragment::limit(new Name('foo'), $int); + Fragment::of(Str::of("{#list:$int}")); }); } @@ -69,23 +68,23 @@ public function testExpand() $this->assertSame( '#/foo/b', - Fragment::limit(new Name('path'), 6)->expand($variables), + Fragment::of(Str::of('{#path:6}'))->expand($variables), ); $this->assertSame( '#red,green,blue', - (new Fragment(new Name('list')))->expand($variables), + Fragment::of(Str::of('{#list}'))->expand($variables), ); $this->assertSame( '#red,green,blue', - Fragment::explode(new Name('list'))->expand($variables), + Fragment::of(Str::of('{#list*}'))->expand($variables), ); $this->assertSame( '#semi,;,dot,.,comma,,', - (new Fragment(new Name('keys')))->expand($variables), + Fragment::of(Str::of('{#keys}'))->expand($variables), ); $this->assertSame( '#semi=;,dot=.,comma=,', - Fragment::explode(new Name('keys'))->expand($variables), + Fragment::of(Str::of('{#keys*}'))->expand($variables), ); } diff --git a/tests/Expression/Level4/LabelTest.php b/tests/Expression/Level4/LabelTest.php index ce062e8..b152f04 100644 --- a/tests/Expression/Level4/LabelTest.php +++ b/tests/Expression/Level4/LabelTest.php @@ -5,7 +5,6 @@ use Innmind\UrlTemplate\{ Expression\Level4\Label, - Expression\Name, Expression, Exception\DomainException, Exception\LogicException, @@ -28,23 +27,23 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Label(new Name('foo')), + Label::of(Str::of('{.foo}')), ); $this->assertInstanceOf( Expression::class, - Label::explode(new Name('foo')), + Label::of(Str::of('{.foo*}')), ); $this->assertInstanceOf( Expression::class, - Label::limit(new Name('foo'), 42), + Label::of(Str::of('{.foo:42}')), ); } public function testStringCast() { - $this->assertSame('{.foo}', (new Label(new Name('foo')))->toString()); - $this->assertSame('{.foo*}', Label::explode(new Name('foo'))->toString()); - $this->assertSame('{.foo:42}', Label::limit(new Name('foo'), 42)->toString()); + $this->assertSame('{.foo}', Label::of(Str::of('{.foo}'))->toString()); + $this->assertSame('{.foo*}', Label::of(Str::of('{.foo*}'))->toString()); + $this->assertSame('{.foo:42}', Label::of(Str::of('{.foo:42}'))->toString()); } public function testThrowWhenNegativeLimit() @@ -54,7 +53,7 @@ public function testThrowWhenNegativeLimit() ->then(function(int $int): void { $this->expectException(DomainException::class); - Label::limit(new Name('foo'), $int); + Label::of(Str::of("{.foo:$int}")); }); } @@ -69,23 +68,23 @@ public function testExpand() $this->assertSame( '.val', - Label::limit(new Name('var'), 3)->expand($variables), + Label::of(Str::of('{.var:3}'))->expand($variables), ); $this->assertSame( '.red,green,blue', - (new Label(new Name('list')))->expand($variables), + Label::of(Str::of('{.list}'))->expand($variables), ); $this->assertSame( '.red.green.blue', - Label::explode(new Name('list'))->expand($variables), + Label::of(Str::of('{.list*}'))->expand($variables), ); $this->assertSame( '.semi,%3B,dot,.,comma,%2C', - (new Label(new Name('keys')))->expand($variables), + Label::of(Str::of('{.keys}'))->expand($variables), ); $this->assertSame( '.semi=%3B.dot=..comma=%2C', - Label::explode(new Name('keys'))->expand($variables), + Label::of(Str::of('{.keys*}'))->expand($variables), ); } diff --git a/tests/Expression/Level4/ParametersTest.php b/tests/Expression/Level4/ParametersTest.php index ddce300..afccd84 100644 --- a/tests/Expression/Level4/ParametersTest.php +++ b/tests/Expression/Level4/ParametersTest.php @@ -5,7 +5,6 @@ use Innmind\UrlTemplate\{ Expression\Level4\Parameters, - Expression\Name, Expression, Exception\DomainException, Exception\LogicException, @@ -28,23 +27,23 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Parameters(new Name('foo')), + Parameters::of(Str::of('{;foo}')), ); $this->assertInstanceOf( Expression::class, - Parameters::explode(new Name('foo')), + Parameters::of(Str::of('{;foo*}')), ); $this->assertInstanceOf( Expression::class, - Parameters::limit(new Name('foo'), 42), + Parameters::of(Str::of('{;foo:42}')), ); } public function testStringCast() { - $this->assertSame('{;foo}', (new Parameters(new Name('foo')))->toString()); - $this->assertSame('{;foo*}', Parameters::explode(new Name('foo'))->toString()); - $this->assertSame('{;foo:42}', Parameters::limit(new Name('foo'), 42)->toString()); + $this->assertSame('{;foo}', Parameters::of(Str::of('{;foo}'))->toString()); + $this->assertSame('{;foo*}', Parameters::of(Str::of('{;foo*}'))->toString()); + $this->assertSame('{;foo:42}', Parameters::of(Str::of('{;foo:42}'))->toString()); } public function testThrowWhenNegativeLimit() @@ -54,7 +53,7 @@ public function testThrowWhenNegativeLimit() ->then(function(int $int): void { $this->expectException(DomainException::class); - Parameters::limit(new Name('foo'), $int); + Parameters::of(Str::of("{;foo:$int}")); }); } @@ -69,23 +68,23 @@ public function testExpand() $this->assertSame( ';hello=Hello', - Parameters::limit(new Name('hello'), 5)->expand($variables), + Parameters::of(Str::of('{;hello:5}'))->expand($variables), ); $this->assertSame( ';list=red,green,blue', - (new Parameters(new Name('list')))->expand($variables), + Parameters::of(Str::of('{;list}'))->expand($variables), ); $this->assertSame( ';list=red;list=green;list=blue', - Parameters::explode(new Name('list'))->expand($variables), + Parameters::of(Str::of('{;list*}'))->expand($variables), ); $this->assertSame( ';keys=semi,%3B,dot,.,comma,%2C', - (new Parameters(new Name('keys')))->expand($variables), + Parameters::of(Str::of('{;keys}'))->expand($variables), ); $this->assertSame( ';semi=%3B;dot=.;comma=%2C', - Parameters::explode(new Name('keys'))->expand($variables), + Parameters::of(Str::of('{;keys*}'))->expand($variables), ); } diff --git a/tests/Expression/Level4/PathTest.php b/tests/Expression/Level4/PathTest.php index f6253d7..1c64403 100644 --- a/tests/Expression/Level4/PathTest.php +++ b/tests/Expression/Level4/PathTest.php @@ -5,7 +5,6 @@ use Innmind\UrlTemplate\{ Expression\Level4\Path, - Expression\Name, Expression, Exception\DomainException, Exception\LogicException, @@ -28,23 +27,23 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Path(new Name('foo')), + Path::of(Str::of('{/foo}')), ); $this->assertInstanceOf( Expression::class, - Path::explode(new Name('foo')), + Path::of(Str::of('{/foo*}')), ); $this->assertInstanceOf( Expression::class, - Path::limit(new Name('foo'), 42), + Path::of(Str::of('{/foo:42}')), ); } public function testStringCast() { - $this->assertSame('{/foo}', (new Path(new Name('foo')))->toString()); - $this->assertSame('{/foo*}', Path::explode(new Name('foo'))->toString()); - $this->assertSame('{/foo:42}', Path::limit(new Name('foo'), 42)->toString()); + $this->assertSame('{/foo}', Path::of(Str::of('{/foo}'))->toString()); + $this->assertSame('{/foo*}', Path::of(Str::of('{/foo*}'))->toString()); + $this->assertSame('{/foo:42}', Path::of(Str::of('{/foo:42}'))->toString()); } public function testThrowWhenNegativeLimit() @@ -54,7 +53,7 @@ public function testThrowWhenNegativeLimit() ->then(function(int $int): void { $this->expectException(DomainException::class); - Path::limit(new Name('foo'), $int); + Path::of(Str::of("{/foo:$int}")); }); } @@ -69,19 +68,19 @@ public function testExpand() $this->assertSame( '/red,green,blue', - (new Path(new Name('list')))->expand($variables), + Path::of(Str::of('{/list}'))->expand($variables), ); $this->assertSame( '/red/green/blue', - Path::explode(new Name('list'))->expand($variables), + Path::of(Str::of('{/list*}'))->expand($variables), ); $this->assertSame( '/semi,%3B,dot,.,comma,%2C', - (new Path(new Name('keys')))->expand($variables), + Path::of(Str::of('{/keys}'))->expand($variables), ); $this->assertSame( '/semi=%3B/dot=./comma=%2C', - Path::explode(new Name('keys'))->expand($variables), + Path::of(Str::of('{/keys*}'))->expand($variables), ); } diff --git a/tests/Expression/Level4/QueryContinuationTest.php b/tests/Expression/Level4/QueryContinuationTest.php index 2ca8a36..d711f25 100644 --- a/tests/Expression/Level4/QueryContinuationTest.php +++ b/tests/Expression/Level4/QueryContinuationTest.php @@ -5,7 +5,6 @@ use Innmind\UrlTemplate\{ Expression\Level4\QueryContinuation, - Expression\Name, Expression, Exception\DomainException, Exception\LogicException, @@ -28,23 +27,23 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new QueryContinuation(new Name('foo')), + QueryContinuation::of(Str::of('{&foo}')), ); $this->assertInstanceOf( Expression::class, - QueryContinuation::explode(new Name('foo')), + QueryContinuation::of(Str::of('{&foo*}')), ); $this->assertInstanceOf( Expression::class, - QueryContinuation::limit(new Name('foo'), 42), + QueryContinuation::of(Str::of('{&foo:42}')), ); } public function testStringCast() { - $this->assertSame('{&foo}', (new QueryContinuation(new Name('foo')))->toString()); - $this->assertSame('{&foo*}', QueryContinuation::explode(new Name('foo'))->toString()); - $this->assertSame('{&foo:42}', QueryContinuation::limit(new Name('foo'), 42)->toString()); + $this->assertSame('{&foo}', QueryContinuation::of(Str::of('{&foo}'))->toString()); + $this->assertSame('{&foo*}', QueryContinuation::of(Str::of('{&foo*}'))->toString()); + $this->assertSame('{&foo:42}', QueryContinuation::of(Str::of('{&foo:42}'))->toString()); } public function testThrowWhenNegativeLimit() @@ -54,7 +53,7 @@ public function testThrowWhenNegativeLimit() ->then(function(int $int): void { $this->expectException(DomainException::class); - QueryContinuation::limit(new Name('foo'), $int); + QueryContinuation::of(Str::of("{&foo:$int}")); }); } @@ -69,23 +68,23 @@ public function testExpand() $this->assertSame( '&var=val', - QueryContinuation::limit(new Name('var'), 3)->expand($variables), + QueryContinuation::of(Str::of('{&var:3}'))->expand($variables), ); $this->assertSame( '&list=red,green,blue', - (new QueryContinuation(new Name('list')))->expand($variables), + QueryContinuation::of(Str::of('{&list}'))->expand($variables), ); $this->assertSame( '&list=red&list=green&list=blue', - QueryContinuation::explode(new Name('list'))->expand($variables), + QueryContinuation::of(Str::of('{&list*}'))->expand($variables), ); $this->assertSame( '&keys=semi,%3B,dot,.,comma,%2C', - (new QueryContinuation(new Name('keys')))->expand($variables), + QueryContinuation::of(Str::of('{&keys}'))->expand($variables), ); $this->assertSame( '&semi=%3B&dot=.&comma=%2C', - QueryContinuation::explode(new Name('keys'))->expand($variables), + QueryContinuation::of(Str::of('{&keys*}'))->expand($variables), ); } diff --git a/tests/Expression/Level4/QueryTest.php b/tests/Expression/Level4/QueryTest.php index e021d4c..efbb99d 100644 --- a/tests/Expression/Level4/QueryTest.php +++ b/tests/Expression/Level4/QueryTest.php @@ -5,7 +5,6 @@ use Innmind\UrlTemplate\{ Expression\Level4\Query, - Expression\Name, Expression, Exception\DomainException, Exception\LogicException, @@ -28,23 +27,23 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Query(new Name('foo')), + Query::of(Str::of('{?foo}')), ); $this->assertInstanceOf( Expression::class, - Query::explode(new Name('foo')), + Query::of(Str::of('{?foo*}')), ); $this->assertInstanceOf( Expression::class, - Query::limit(new Name('foo'), 42), + Query::of(Str::of('{?foo:42}')), ); } public function testStringCast() { - $this->assertSame('{?foo}', (new Query(new Name('foo')))->toString()); - $this->assertSame('{?foo*}', Query::explode(new Name('foo'))->toString()); - $this->assertSame('{?foo:42}', Query::limit(new Name('foo'), 42)->toString()); + $this->assertSame('{?foo}', Query::of(Str::of('{?foo}'))->toString()); + $this->assertSame('{?foo*}', Query::of(Str::of('{?foo*}'))->toString()); + $this->assertSame('{?foo:42}', Query::of(Str::of('{?foo:42}'))->toString()); } public function testThrowWhenNegativeLimit() @@ -54,7 +53,7 @@ public function testThrowWhenNegativeLimit() ->then(function(int $int): void { $this->expectException(DomainException::class); - Query::limit(new Name('foo'), $int); + Query::of(Str::of("{?foo:$int}")); }); } @@ -69,23 +68,23 @@ public function testExpand() $this->assertSame( '?var=val', - Query::limit(new Name('var'), 3)->expand($variables), + Query::of(Str::of('{?var:3}'))->expand($variables), ); $this->assertSame( '?list=red,green,blue', - (new Query(new Name('list')))->expand($variables), + Query::of(Str::of('{?list}'))->expand($variables), ); $this->assertSame( '?list=red&list=green&list=blue', - Query::explode(new Name('list'))->expand($variables), + Query::of(Str::of('{?list*}'))->expand($variables), ); $this->assertSame( '?keys=semi,%3B,dot,.,comma,%2C', - (new Query(new Name('keys')))->expand($variables), + Query::of(Str::of('{?keys}'))->expand($variables), ); $this->assertSame( '?semi=%3B&dot=.&comma=%2C', - Query::explode(new Name('keys'))->expand($variables), + Query::of(Str::of('{?keys*}'))->expand($variables), ); } diff --git a/tests/Expression/Level4/ReservedTest.php b/tests/Expression/Level4/ReservedTest.php index b50aab4..c3c9f47 100644 --- a/tests/Expression/Level4/ReservedTest.php +++ b/tests/Expression/Level4/ReservedTest.php @@ -5,7 +5,6 @@ use Innmind\UrlTemplate\{ Expression\Level4\Reserved, - Expression\Name, Expression, Exception\DomainException, Exception\LogicException, @@ -28,23 +27,23 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Reserved(new Name('foo')), + Reserved::of(Str::of('{+foo}')), ); $this->assertInstanceOf( Expression::class, - Reserved::explode(new Name('foo')), + Reserved::of(Str::of('{+foo*}')), ); $this->assertInstanceOf( Expression::class, - Reserved::limit(new Name('foo'), 42), + Reserved::of(Str::of('{+foo:42}')), ); } public function testStringCast() { - $this->assertSame('{+foo}', (new Reserved(new Name('foo')))->toString()); - $this->assertSame('{+foo*}', Reserved::explode(new Name('foo'))->toString()); - $this->assertSame('{+foo:42}', Reserved::limit(new Name('foo'), 42)->toString()); + $this->assertSame('{+foo}', Reserved::of(Str::of('{+foo}'))->toString()); + $this->assertSame('{+foo*}', Reserved::of(Str::of('{+foo*}'))->toString()); + $this->assertSame('{+foo:42}', Reserved::of(Str::of('{+foo:42}'))->toString()); } public function testThrowWhenNegativeLimit() @@ -54,7 +53,7 @@ public function testThrowWhenNegativeLimit() ->then(function(int $int): void { $this->expectException(DomainException::class); - Reserved::limit(new Name('foo'), $int); + Reserved::of(Str::of("{+foo:$int}")); }); } @@ -69,23 +68,23 @@ public function testExpand() $this->assertSame( '/foo/b', - Reserved::limit(new Name('path'), 6)->expand($variables), + Reserved::of(Str::of('{+path:6}'))->expand($variables), ); $this->assertSame( 'red,green,blue', - (new Reserved(new Name('list')))->expand($variables), + Reserved::of(Str::of('{+list}'))->expand($variables), ); $this->assertSame( 'red,green,blue', - Reserved::explode(new Name('list'))->expand($variables), + Reserved::of(Str::of('{+list*}'))->expand($variables), ); $this->assertSame( 'semi,;,dot,.,comma,,', - (new Reserved(new Name('keys')))->expand($variables), + Reserved::of(Str::of('{+keys}'))->expand($variables), ); $this->assertSame( 'semi=;,dot=.,comma=,', - Reserved::explode(new Name('keys'))->expand($variables), + Reserved::of(Str::of('{+keys*}'))->expand($variables), ); } diff --git a/tests/Expression/Level4Test.php b/tests/Expression/Level4Test.php index f2b6438..dd7bb2d 100644 --- a/tests/Expression/Level4Test.php +++ b/tests/Expression/Level4Test.php @@ -5,7 +5,6 @@ use Innmind\UrlTemplate\{ Expression\Level4, - Expression\Name, Expression, Exception\DomainException, Exception\LogicException, @@ -28,23 +27,23 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Level4(new Name('foo')), + Level4::of(Str::of('{foo}')), ); $this->assertInstanceOf( Expression::class, - Level4::explode(new Name('foo')), + Level4::of(Str::of('{foo*}')), ); $this->assertInstanceOf( Expression::class, - Level4::limit(new Name('foo'), 42), + Level4::of(Str::of('{foo:42}')), ); } public function testStringCast() { - $this->assertSame('{foo}', (new Level4(new Name('foo')))->toString()); - $this->assertSame('{foo*}', Level4::explode(new Name('foo'))->toString()); - $this->assertSame('{foo:42}', Level4::limit(new Name('foo'), 42)->toString()); + $this->assertSame('{foo}', Level4::of(Str::of('{foo}'))->toString()); + $this->assertSame('{foo*}', Level4::of(Str::of('{foo*}'))->toString()); + $this->assertSame('{foo:42}', Level4::of(Str::of('{foo:42}'))->toString()); } public function testThrowWhenNegativeLimit() @@ -54,7 +53,7 @@ public function testThrowWhenNegativeLimit() ->then(function(int $int): void { $this->expectException(DomainException::class); - Level4::limit(new Name('foo'), $int); + Level4::of(Str::of("{foo:$int}")); }); } @@ -69,31 +68,31 @@ public function testExpand() $this->assertSame( 'val', - Level4::limit(new Name('var'), 3)->expand($variables), + Level4::of(Str::of('{var:3}'))->expand($variables), ); $this->assertSame( 'value', - Level4::limit(new Name('var'), 30)->expand($variables), + Level4::of(Str::of('{var:30}'))->expand($variables), ); $this->assertSame( '%2Ffoo', - Level4::limit(new Name('path'), 4)->expand($variables), + Level4::of(Str::of('{path:4}'))->expand($variables), ); $this->assertSame( 'red,green,blue', - (new Level4(new Name('list')))->expand($variables), + Level4::of(Str::of('{list}'))->expand($variables), ); $this->assertSame( 'red,green,blue', - Level4::explode(new Name('list'))->expand($variables), + Level4::of(Str::of('{list*}'))->expand($variables), ); $this->assertSame( 'semi,%3B,dot,.,comma,%2C', - (new Level4(new Name('keys')))->expand($variables), + Level4::of(Str::of('{keys}'))->expand($variables), ); $this->assertSame( 'semi=%3B,dot=.,comma=%2C', - Level4::explode(new Name('keys'))->expand($variables), + Level4::of(Str::of('{keys*}'))->expand($variables), ); } diff --git a/tests/Expression/NameTest.php b/tests/Expression/NameTest.php index 5e6c3c2..57a329a 100644 --- a/tests/Expression/NameTest.php +++ b/tests/Expression/NameTest.php @@ -26,7 +26,7 @@ public function testInterface() }), ) ->then(function(string $string): void { - $this->assertSame($string, (new Name($string))->toString()); + $this->assertSame($string, Name::of($string)->toString()); }); } @@ -42,7 +42,7 @@ public function testThrowWhenInvalidName() $this->expectException(DomainException::class); $this->expectExceptionMessage($string); - new Name($string); + Name::of($string); }); } } From beff664bc3170decf2ccd95d2e79cb409055b8df Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 30 Jul 2022 17:31:28 +0200 Subject: [PATCH 13/39] deduplicate the code to parse level4 strings --- src/Expression/Level4.php | 33 +++-------- src/Expression/Level4/Fragment.php | 34 +++-------- src/Expression/Level4/Label.php | 34 +++-------- src/Expression/Level4/Parameters.php | 34 +++-------- src/Expression/Level4/Parse.php | 66 +++++++++++++++++++++ src/Expression/Level4/Path.php | 34 +++-------- src/Expression/Level4/Query.php | 34 +++-------- src/Expression/Level4/QueryContinuation.php | 34 +++-------- src/Expression/Level4/Reserved.php | 34 +++-------- 9 files changed, 137 insertions(+), 200 deletions(-) create mode 100644 src/Expression/Level4/Parse.php diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index 20163e7..1406126 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -6,9 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Level4\Composite, - Exception\DomainException, Exception\ExplodeExpressionCantBeMatched, - Exception\ExpressionLimitCantBeNegative, }; use Innmind\Immutable\{ Map, @@ -39,36 +37,21 @@ private function __construct(Name $name) */ public static function of(Str $string): Expression { - if ($string->matches('~^\{[a-zA-Z0-9_]+\}$~')) { - return new self(Name::of($string->trim('{}')->toString())); - } - - if ($string->matches('~^\{[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(Name::of($string->trim('{*}')->toString())); - } - - if ($string->matches('~^\{[a-zA-Z0-9_]+:\d+\}$~')) { - $string = $string->trim('{}'); - [$name, $limit] = $string->split(':')->toList(); - - return self::limit( - Name::of($name->toString()), - (int) $limit->toString(), - ); - } - - throw new DomainException($string->toString()); + return Level4\Parse::of( + $string, + static fn(Name $name) => new self($name), + self::explode(...), + self::limit(...), + ); } /** * @psalm-pure + * + * @param int<0, max> $limit */ public static function limit(Name $name, int $limit): self { - if ($limit < 0) { - throw new ExpressionLimitCantBeNegative($limit); - } - $self = new self($name); $self->limit = $limit; diff --git a/src/Expression/Level4/Fragment.php b/src/Expression/Level4/Fragment.php index a70e527..c64ad4d 100644 --- a/src/Expression/Level4/Fragment.php +++ b/src/Expression/Level4/Fragment.php @@ -8,9 +8,7 @@ Expression\Name, Expression\Level2, Expression\Level4, - Exception\DomainException, Exception\LogicException, - Exception\ExpressionLimitCantBeNegative, }; use Innmind\Immutable\{ Map, @@ -36,36 +34,22 @@ private function __construct(Name $name) */ public static function of(Str $string): Expression { - if ($string->matches('~^\{#[a-zA-Z0-9_]+\}$~')) { - return new self(Name::of($string->trim('{#}')->toString())); - } - - if ($string->matches('~^\{#[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(Name::of($string->trim('{#*}')->toString())); - } - - if ($string->matches('~^\{#[a-zA-Z0-9_]+:\d+\}$~')) { - $string = $string->trim('{#}'); - [$name, $limit] = $string->split(':')->toList(); - - return self::limit( - Name::of($name->toString()), - (int) $limit->toString(), - ); - } - - throw new DomainException($string->toString()); + return Parse::of( + $string, + static fn(Name $name) => new self($name), + self::explode(...), + self::limit(...), + '#', + ); } /** * @psalm-pure + * + * @param int<0, max> $limit */ public static function limit(Name $name, int $limit): self { - if ($limit < 0) { - throw new ExpressionLimitCantBeNegative($limit); - } - $self = new self($name); $self->expression = Level4::limit($name, $limit) ->withLead('#') diff --git a/src/Expression/Level4/Label.php b/src/Expression/Level4/Label.php index ff4207c..cf17e06 100644 --- a/src/Expression/Level4/Label.php +++ b/src/Expression/Level4/Label.php @@ -8,8 +8,6 @@ Expression\Name, Expression\Level1, Expression\Level4, - Exception\DomainException, - Exception\ExpressionLimitCantBeNegative, }; use Innmind\Immutable\{ Map, @@ -33,36 +31,22 @@ private function __construct(Name $name) */ public static function of(Str $string): Expression { - if ($string->matches('~^\{\.[a-zA-Z0-9_]+\}$~')) { - return new self(Name::of($string->trim('{.}')->toString())); - } - - if ($string->matches('~^\{\.[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(Name::of($string->trim('{.*}')->toString())); - } - - if ($string->matches('~^\{\.[a-zA-Z0-9_]+:\d+\}$~')) { - $string = $string->trim('{.}'); - [$name, $limit] = $string->split(':')->toList(); - - return self::limit( - Name::of($name->toString()), - (int) $limit->toString(), - ); - } - - throw new DomainException($string->toString()); + return Parse::of( + $string, + static fn(Name $name) => new self($name), + self::explode(...), + self::limit(...), + '.', + ); } /** * @psalm-pure + * + * @param int<0, max> $limit */ public static function limit(Name $name, int $limit): self { - if ($limit < 0) { - throw new ExpressionLimitCantBeNegative($limit); - } - $self = new self($name); $self->expression = Level4::limit($name, $limit)->withLead('.'); diff --git a/src/Expression/Level4/Parameters.php b/src/Expression/Level4/Parameters.php index 21c29a3..bbc12ca 100644 --- a/src/Expression/Level4/Parameters.php +++ b/src/Expression/Level4/Parameters.php @@ -9,9 +9,7 @@ Expression\Level1, Expression\Level3, Expression\Level4, - Exception\DomainException, Exception\ExplodeExpressionCantBeMatched, - Exception\ExpressionLimitCantBeNegative, }; use Innmind\Immutable\{ Map, @@ -40,36 +38,22 @@ private function __construct(Name $name) */ public static function of(Str $string): Expression { - if ($string->matches('~^\{;[a-zA-Z0-9_]+\}$~')) { - return new self(Name::of($string->trim('{;}')->toString())); - } - - if ($string->matches('~^\{;[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(Name::of($string->trim('{;*}')->toString())); - } - - if ($string->matches('~^\{;[a-zA-Z0-9_]+:\d+\}$~')) { - $string = $string->trim('{;}'); - [$name, $limit] = $string->split(':')->toList(); - - return self::limit( - Name::of($name->toString()), - (int) $limit->toString(), - ); - } - - throw new DomainException($string->toString()); + return Parse::of( + $string, + static fn(Name $name) => new self($name), + self::explode(...), + self::limit(...), + ';', + ); } /** * @psalm-pure + * + * @param int<0, max> $limit */ public static function limit(Name $name, int $limit): self { - if ($limit < 0) { - throw new ExpressionLimitCantBeNegative($limit); - } - $self = new self($name); $self->limit = $limit; diff --git a/src/Expression/Level4/Parse.php b/src/Expression/Level4/Parse.php new file mode 100644 index 0000000..beade7e --- /dev/null +++ b/src/Expression/Level4/Parse.php @@ -0,0 +1,66 @@ +): T $limit + * @param non-empty-string|null $lead + * + * @return T + */ + public static function of( + Str $string, + callable $standard, + callable $explode, + callable $limit, + string $lead = null, + ): Expression { + $drop = match ($lead) { + null => 1, + default => 2, + }; + $lead = match ($lead) { + null => '', + default => "\\$lead", + }; + + if ($string->matches("~^\{{$lead}[a-zA-Z0-9_]+\}\$~")) { + return $standard(Name::of($string->drop($drop)->dropEnd(1)->toString())); + } + + if ($string->matches("~^\{{$lead}[a-zA-Z0-9_]+\*\}\$~")) { + return $explode(Name::of($string->drop($drop)->dropEnd(2)->toString())); + } + + if ($string->matches("~^\{{$lead}[a-zA-Z0-9_]+:\d+\}\$~")) { + $string = $string->drop($drop)->dropEnd(1); + [$name, $int] = $string->split(':')->toList(); + $int = (int) $int->toString(); + + if ($int < 0) { + throw new ExpressionLimitCantBeNegative($int); + } + + /** @psalm-suppress ArgumentTypeCoercion */ + return $limit(Name::of($name->toString()), $int); + } + + throw new DomainException($string->toString()); + } +} diff --git a/src/Expression/Level4/Path.php b/src/Expression/Level4/Path.php index edcb5d3..a3eb251 100644 --- a/src/Expression/Level4/Path.php +++ b/src/Expression/Level4/Path.php @@ -8,8 +8,6 @@ Expression\Name, Expression\Level1, Expression\Level4, - Exception\DomainException, - Exception\ExpressionLimitCantBeNegative, }; use Innmind\Immutable\{ Map, @@ -33,36 +31,22 @@ private function __construct(Name $name) */ public static function of(Str $string): Expression { - if ($string->matches('~^\{/[a-zA-Z0-9_]+\}$~')) { - return new self(Name::of($string->trim('{/}')->toString())); - } - - if ($string->matches('~^\{/[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(Name::of($string->trim('{/*}')->toString())); - } - - if ($string->matches('~^\{/[a-zA-Z0-9_]+:\d+\}$~')) { - $string = $string->trim('{/}'); - [$name, $limit] = $string->split(':')->toList(); - - return self::limit( - Name::of($name->toString()), - (int) $limit->toString(), - ); - } - - throw new DomainException($string->toString()); + return Parse::of( + $string, + static fn(Name $name) => new self($name), + self::explode(...), + self::limit(...), + '/', + ); } /** * @psalm-pure + * + * @param int<0, max> $limit */ public static function limit(Name $name, int $limit): self { - if ($limit < 0) { - throw new ExpressionLimitCantBeNegative($limit); - } - $self = new self($name); $self->expression = Level4::limit($name, $limit)->withLead('/'); diff --git a/src/Expression/Level4/Query.php b/src/Expression/Level4/Query.php index 681c0f1..a1aff15 100644 --- a/src/Expression/Level4/Query.php +++ b/src/Expression/Level4/Query.php @@ -9,9 +9,7 @@ Expression\Level1, Expression\Level3, Expression\Level4, - Exception\DomainException, Exception\ExplodeExpressionCantBeMatched, - Exception\ExpressionLimitCantBeNegative, }; use Innmind\Immutable\{ Map, @@ -40,36 +38,22 @@ private function __construct(Name $name) */ public static function of(Str $string): Expression { - if ($string->matches('~^\{\?[a-zA-Z0-9_]+\}$~')) { - return new self(Name::of($string->trim('{?}')->toString())); - } - - if ($string->matches('~^\{\?[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(Name::of($string->trim('{?*}')->toString())); - } - - if ($string->matches('~^\{\?[a-zA-Z0-9_]+:\d+\}$~')) { - $string = $string->trim('{?}'); - [$name, $limit] = $string->split(':')->toList(); - - return self::limit( - Name::of($name->toString()), - (int) $limit->toString(), - ); - } - - throw new DomainException($string->toString()); + return Parse::of( + $string, + static fn(Name $name) => new self($name), + self::explode(...), + self::limit(...), + '?', + ); } /** * @psalm-pure + * + * @param int<0, max> $limit */ public static function limit(Name $name, int $limit): self { - if ($limit < 0) { - throw new ExpressionLimitCantBeNegative($limit); - } - $self = new self($name); $self->limit = $limit; diff --git a/src/Expression/Level4/QueryContinuation.php b/src/Expression/Level4/QueryContinuation.php index 6871eea..c8839fe 100644 --- a/src/Expression/Level4/QueryContinuation.php +++ b/src/Expression/Level4/QueryContinuation.php @@ -9,9 +9,7 @@ Expression\Level1, Expression\Level3, Expression\Level4, - Exception\DomainException, Exception\ExplodeExpressionCantBeMatched, - Exception\ExpressionLimitCantBeNegative, }; use Innmind\Immutable\{ Map, @@ -40,36 +38,22 @@ private function __construct(Name $name) */ public static function of(Str $string): Expression { - if ($string->matches('~^\{\&[a-zA-Z0-9_]+\}$~')) { - return new self(Name::of($string->trim('{&}')->toString())); - } - - if ($string->matches('~^\{\&[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(Name::of($string->trim('{&*}')->toString())); - } - - if ($string->matches('~^\{\&[a-zA-Z0-9_]+:\d+\}$~')) { - $string = $string->trim('{&}'); - [$name, $limit] = $string->split(':')->toList(); - - return self::limit( - Name::of($name->toString()), - (int) $limit->toString(), - ); - } - - throw new DomainException($string->toString()); + return Parse::of( + $string, + static fn(Name $name) => new self($name), + self::explode(...), + self::limit(...), + '&', + ); } /** * @psalm-pure + * + * @param int<0, max> $limit */ public static function limit(Name $name, int $limit): self { - if ($limit < 0) { - throw new ExpressionLimitCantBeNegative($limit); - } - $self = new self($name); $self->limit = $limit; diff --git a/src/Expression/Level4/Reserved.php b/src/Expression/Level4/Reserved.php index 4218015..2f78ca4 100644 --- a/src/Expression/Level4/Reserved.php +++ b/src/Expression/Level4/Reserved.php @@ -8,9 +8,7 @@ Expression\Name, Expression\Level2, Expression\Level4, - Exception\DomainException, Exception\ExplodeExpressionCantBeMatched, - Exception\ExpressionLimitCantBeNegative, }; use Innmind\Immutable\{ Map, @@ -40,36 +38,22 @@ private function __construct(Name $name) */ public static function of(Str $string): Expression { - if ($string->matches('~^\{\+[a-zA-Z0-9_]+\}$~')) { - return new self(Name::of($string->trim('{+}')->toString())); - } - - if ($string->matches('~^\{\+[a-zA-Z0-9_]+\*\}$~')) { - return self::explode(Name::of($string->trim('{+*}')->toString())); - } - - if ($string->matches('~^\{\+[a-zA-Z0-9_]+:\d+\}$~')) { - $string = $string->trim('{+}'); - [$name, $limit] = $string->split(':')->toList(); - - return self::limit( - Name::of($name->toString()), - (int) $limit->toString(), - ); - } - - throw new DomainException($string->toString()); + return Parse::of( + $string, + static fn(Name $name) => new self($name), + self::explode(...), + self::limit(...), + '+', + ); } /** * @psalm-pure + * + * @param int<0, max> $limit */ public static function limit(Name $name, int $limit): self { - if ($limit < 0) { - throw new ExpressionLimitCantBeNegative($limit); - } - $self = new self($name); $self->limit = $limit; $self->expression = Level4::limit($name, $limit)->withExpression( From 866fd632b47a016014d1a8e461eb2c2bd6ba6965 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 30 Jul 2022 17:48:07 +0200 Subject: [PATCH 14/39] the limit must be positive --- src/Expression/Level4.php | 10 +++++++--- src/Expression/Level4/Composite.php | 4 ++-- src/Expression/Level4/Fragment.php | 2 +- src/Expression/Level4/Label.php | 2 +- src/Expression/Level4/Parameters.php | 10 +++++++--- src/Expression/Level4/Parse.php | 4 ++-- src/Expression/Level4/Path.php | 2 +- src/Expression/Level4/Query.php | 12 ++++++++---- src/Expression/Level4/QueryContinuation.php | 10 +++++++--- src/Expression/Level4/Reserved.php | 3 ++- 10 files changed, 38 insertions(+), 21 deletions(-) diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index 1406126..69330cf 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -21,6 +21,7 @@ final class Level4 implements Expression { private Name $name; private Expression $expression; + /** @var ?positive-int */ private ?int $limit = null; private bool $explode = false; private string $lead = ''; @@ -48,7 +49,7 @@ public static function of(Str $string): Expression /** * @psalm-pure * - * @param int<0, max> $limit + * @param positive-int $limit */ public static function limit(Name $name, int $limit): self { @@ -137,7 +138,7 @@ public function expand(Map $variables): string } if ($this->mustLimit()) { - $value = Str::of((string) $variable)->substring(0, $this->limit); + $value = Str::of((string) $variable)->take($this->limit); $value = $this->expression->expand( ($variables)($this->name->toString(), $value->toString()), ); @@ -157,7 +158,7 @@ public function regex(): string if ($this->mustLimit()) { // replace '*' match by the actual limit $regex = Str::of($this->expression->regex()) - ->substring(0, -2) + ->dropEnd(2) ->append("{{$this->limit}})") ->toString(); } else { @@ -184,6 +185,9 @@ public function toString(): string return "{{$this->lead}{$this->name->toString()}}"; } + /** + * @psalm-assert-if-true positive-int $this->limit + */ private function mustLimit(): bool { return \is_int($this->limit); diff --git a/src/Expression/Level4/Composite.php b/src/Expression/Level4/Composite.php index 1f5b747..e358eaa 100644 --- a/src/Expression/Level4/Composite.php +++ b/src/Expression/Level4/Composite.php @@ -96,7 +96,7 @@ public function expand(Map $variables): string ->append( $expanded->drop(1)->map(function(string $value): string { if ($this->removeLead) { - return Str::of($value)->substring(1)->toString(); + return Str::of($value)->drop(1)->toString(); } return $value; @@ -113,7 +113,7 @@ public function regex(): string ->drop(1) ->map(function(Expression $expression): string { if ($this->removeLead) { - return Str::of($expression->regex())->substring(2)->toString(); + return Str::of($expression->regex())->drop(2)->toString(); } return $expression->regex(); diff --git a/src/Expression/Level4/Fragment.php b/src/Expression/Level4/Fragment.php index c64ad4d..dda28f1 100644 --- a/src/Expression/Level4/Fragment.php +++ b/src/Expression/Level4/Fragment.php @@ -46,7 +46,7 @@ public static function of(Str $string): Expression /** * @psalm-pure * - * @param int<0, max> $limit + * @param positive-int $limit */ public static function limit(Name $name, int $limit): self { diff --git a/src/Expression/Level4/Label.php b/src/Expression/Level4/Label.php index cf17e06..a9e9561 100644 --- a/src/Expression/Level4/Label.php +++ b/src/Expression/Level4/Label.php @@ -43,7 +43,7 @@ public static function of(Str $string): Expression /** * @psalm-pure * - * @param int<0, max> $limit + * @param positive-int $limit */ public static function limit(Name $name, int $limit): self { diff --git a/src/Expression/Level4/Parameters.php b/src/Expression/Level4/Parameters.php index bbc12ca..bf1dd0a 100644 --- a/src/Expression/Level4/Parameters.php +++ b/src/Expression/Level4/Parameters.php @@ -23,6 +23,7 @@ final class Parameters implements Expression { private Name $name; + /** @var ?positive-int */ private ?int $limit = null; private bool $explode = false; private Expression $expression; @@ -50,7 +51,7 @@ public static function of(Str $string): Expression /** * @psalm-pure * - * @param int<0, max> $limit + * @param positive-int $limit */ public static function limit(Name $name, int $limit): self { @@ -106,7 +107,7 @@ public function expand(Map $variables): string $value = Str::of($this->expression->expand($variables)); if ($this->mustLimit()) { - return ";{$this->name->toString()}={$value->substring(0, $this->limit)->toString()}"; + return ";{$this->name->toString()}={$value->take($this->limit)->toString()}"; } return ";{$this->name->toString()}={$value->toString()}"; @@ -121,7 +122,7 @@ public function regex(): string if ($this->mustLimit()) { // replace '*' match by the actual limit $regex = Str::of($this->expression->regex()) - ->substring(0, -2) + ->dropEnd(2) ->append("{{$this->limit}})") ->toString(); } else { @@ -148,6 +149,9 @@ public function toString(): string return "{;{$this->name->toString()}}"; } + /** + * @psalm-assert-if-true positive-int $this->limit + */ private function mustLimit(): bool { return \is_int($this->limit); diff --git a/src/Expression/Level4/Parse.php b/src/Expression/Level4/Parse.php index beade7e..72bd85c 100644 --- a/src/Expression/Level4/Parse.php +++ b/src/Expression/Level4/Parse.php @@ -19,7 +19,7 @@ final class Parse * * @param pure-callable(Name): T $standard * @param pure-callable(Name): T $explode - * @param pure-callable(Name, int<0, max>): T $limit + * @param pure-callable(Name, positive-int): T $limit * @param non-empty-string|null $lead * * @return T @@ -53,7 +53,7 @@ public static function of( [$name, $int] = $string->split(':')->toList(); $int = (int) $int->toString(); - if ($int < 0) { + if ($int < 1) { throw new ExpressionLimitCantBeNegative($int); } diff --git a/src/Expression/Level4/Path.php b/src/Expression/Level4/Path.php index a3eb251..41a76ab 100644 --- a/src/Expression/Level4/Path.php +++ b/src/Expression/Level4/Path.php @@ -43,7 +43,7 @@ public static function of(Str $string): Expression /** * @psalm-pure * - * @param int<0, max> $limit + * @param positive-int $limit */ public static function limit(Name $name, int $limit): self { diff --git a/src/Expression/Level4/Query.php b/src/Expression/Level4/Query.php index a1aff15..e6bf1a1 100644 --- a/src/Expression/Level4/Query.php +++ b/src/Expression/Level4/Query.php @@ -23,6 +23,7 @@ final class Query implements Expression { private Name $name; + /** @var ?positive-int */ private ?int $limit = null; private bool $explode = false; private Expression $expression; @@ -50,7 +51,7 @@ public static function of(Str $string): Expression /** * @psalm-pure * - * @param int<0, max> $limit + * @param positive-int $limit */ public static function limit(Name $name, int $limit): self { @@ -106,7 +107,7 @@ public function expand(Map $variables): string $value = Str::of($this->expression->expand($variables)); if ($this->mustLimit()) { - return "?{$this->name->toString()}={$value->substring(0, $this->limit)->toString()}"; + return "?{$this->name->toString()}={$value->take($this->limit)->toString()}"; } return "?{$this->name->toString()}={$value->toString()}"; @@ -121,7 +122,7 @@ public function regex(): string if ($this->mustLimit()) { // replace '*' match by the actual limit $regex = Str::of($this->expression->regex()) - ->substring(0, -2) + ->dropEnd(2) ->append("{{$this->limit}})") ->toString(); } else { @@ -148,6 +149,9 @@ public function toString(): string return "{?{$this->name->toString()}}"; } + /** + * @psalm-assert-if-true positive-int $this->limit + */ private function mustLimit(): bool { return \is_int($this->limit); @@ -212,7 +216,7 @@ private function explodeList(Map $variables, array $variablesToExpand): string // the substring is here to remove the '?' as it should be a '&' // done below in the join - return Str::of($value)->substring(1)->toString(); + return Str::of($value)->drop(1)->toString(); }); return Str::of('&') diff --git a/src/Expression/Level4/QueryContinuation.php b/src/Expression/Level4/QueryContinuation.php index c8839fe..de71f4b 100644 --- a/src/Expression/Level4/QueryContinuation.php +++ b/src/Expression/Level4/QueryContinuation.php @@ -23,6 +23,7 @@ final class QueryContinuation implements Expression { private Name $name; + /** @var ?positive-int */ private ?int $limit = null; private bool $explode = false; private Expression $expression; @@ -50,7 +51,7 @@ public static function of(Str $string): Expression /** * @psalm-pure * - * @param int<0, max> $limit + * @param positive-int $limit */ public static function limit(Name $name, int $limit): self { @@ -106,7 +107,7 @@ public function expand(Map $variables): string $value = Str::of($this->expression->expand($variables)); if ($this->mustLimit()) { - return "&{$this->name->toString()}={$value->substring(0, $this->limit)->toString()}"; + return "&{$this->name->toString()}={$value->take($this->limit)->toString()}"; } return "&{$this->name->toString()}={$value->toString()}"; @@ -121,7 +122,7 @@ public function regex(): string if ($this->mustLimit()) { // replace '*' match by the actual limit $regex = Str::of($this->expression->regex()) - ->substring(0, -2) + ->dropEnd(2) ->append("{{$this->limit}})") ->toString(); } else { @@ -148,6 +149,9 @@ public function toString(): string return "{&{$this->name->toString()}}"; } + /** + * @psalm-assert-if-true positive-int $this->limit + */ private function mustLimit(): bool { return \is_int($this->limit); diff --git a/src/Expression/Level4/Reserved.php b/src/Expression/Level4/Reserved.php index 2f78ca4..56ee16c 100644 --- a/src/Expression/Level4/Reserved.php +++ b/src/Expression/Level4/Reserved.php @@ -21,6 +21,7 @@ final class Reserved implements Expression { private Name $name; + /** @var ?positive-int */ private ?int $limit = null; private bool $explode = false; private Expression $expression; @@ -50,7 +51,7 @@ public static function of(Str $string): Expression /** * @psalm-pure * - * @param int<0, max> $limit + * @param positive-int $limit */ public static function limit(Name $name, int $limit): self { From a23f1effe04bab77522f2b0307aaf54e7efd642d Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 12:19:48 +0200 Subject: [PATCH 15/39] use Maybe instead of throwing exceptions --- .../ExpressionLimitCantBeNegative.php | 12 -- src/Expression.php | 9 +- src/Expression/Level1.php | 15 ++- src/Expression/Level2/Fragment.php | 15 ++- src/Expression/Level2/Reserved.php | 15 ++- src/Expression/Level3.php | 29 ++-- src/Expression/Level3/Fragment.php | 25 ++-- src/Expression/Level3/Label.php | 25 ++-- src/Expression/Level3/NamedValues.php | 3 +- src/Expression/Level3/Parameters.php | 25 ++-- src/Expression/Level3/Path.php | 25 ++-- src/Expression/Level3/Query.php | 25 ++-- src/Expression/Level3/QueryContinuation.php | 25 ++-- src/Expression/Level3/Reserved.php | 25 ++-- src/Expression/Level4.php | 9 +- src/Expression/Level4/Composite.php | 41 +++--- src/Expression/Level4/Fragment.php | 9 +- src/Expression/Level4/Label.php | 9 +- src/Expression/Level4/Parameters.php | 9 +- src/Expression/Level4/Parse.php | 98 ++++++++++---- src/Expression/Level4/Path.php | 9 +- src/Expression/Level4/Query.php | 9 +- src/Expression/Level4/QueryContinuation.php | 9 +- src/Expression/Level4/Reserved.php | 9 +- src/Expressions.php | 66 +++++----- tests/Expression/Level1Test.php | 44 +++++-- tests/Expression/Level2/FragmentTest.php | 44 +++++-- tests/Expression/Level2/ReservedTest.php | 44 +++++-- tests/Expression/Level3/FragmentTest.php | 41 ++++-- tests/Expression/Level3/LabelTest.php | 41 ++++-- tests/Expression/Level3/ParametersTest.php | 41 ++++-- tests/Expression/Level3/PathTest.php | 41 ++++-- .../Level3/QueryContinuationTest.php | 41 ++++-- tests/Expression/Level3/QueryTest.php | 41 ++++-- tests/Expression/Level3/ReservedTest.php | 41 ++++-- tests/Expression/Level3Test.php | 41 ++++-- tests/Expression/Level4/CompositeTest.php | 101 ++++++++++---- tests/Expression/Level4/FragmentTest.php | 114 ++++++++++++---- tests/Expression/Level4/LabelTest.php | 114 ++++++++++++---- tests/Expression/Level4/ParametersTest.php | 114 ++++++++++++---- tests/Expression/Level4/PathTest.php | 109 +++++++++++---- .../Level4/QueryContinuationTest.php | 114 ++++++++++++---- tests/Expression/Level4/QueryTest.php | 114 ++++++++++++---- tests/Expression/Level4/ReservedTest.php | 114 ++++++++++++---- tests/Expression/Level4Test.php | 124 ++++++++++++++---- 45 files changed, 1409 insertions(+), 619 deletions(-) delete mode 100644 src/Exception/ExpressionLimitCantBeNegative.php diff --git a/src/Exception/ExpressionLimitCantBeNegative.php b/src/Exception/ExpressionLimitCantBeNegative.php deleted file mode 100644 index ec42071..0000000 --- a/src/Exception/ExpressionLimitCantBeNegative.php +++ /dev/null @@ -1,12 +0,0 @@ - */ - public static function of(Str $string): self; + public static function of(Str $string): Maybe; /** * @param Map $variables diff --git a/src/Expression/Level1.php b/src/Expression/Level1.php index 7aad040..8fd6917 100644 --- a/src/Expression/Level1.php +++ b/src/Expression/Level1.php @@ -6,12 +6,12 @@ use Innmind\UrlTemplate\{ Expression, UrlEncode, - Exception\DomainException, Exception\OnlyScalarCanBeExpandedForExpression, }; use Innmind\Immutable\{ Map, Str, + Maybe, }; /** @@ -31,13 +31,14 @@ private function __construct(Name $name) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { - if (!$string->matches('~^\{[a-zA-Z0-9_]+\}$~')) { - throw new DomainException($string->toString()); - } - - return new self(Name::of($string->trim('{}')->toString())); + /** @var Maybe */ + return Maybe::just($string) + ->filter(static fn($string) => $string->matches('~^\{[a-zA-Z0-9_]+\}$~')) + ->map(static fn($string) => $string->trim('{}')->toString()) + ->map(Name::of(...)) + ->map(static fn($name) => new self($name)); } /** diff --git a/src/Expression/Level2/Fragment.php b/src/Expression/Level2/Fragment.php index 06eb835..780e3c2 100644 --- a/src/Expression/Level2/Fragment.php +++ b/src/Expression/Level2/Fragment.php @@ -7,12 +7,12 @@ Expression, Expression\Name, UrlEncode, - Exception\DomainException, Exception\OnlyScalarCanBeExpandedForExpression, }; use Innmind\Immutable\{ Map, Str, + Maybe, }; /** @@ -32,13 +32,14 @@ private function __construct(Name $name) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { - if (!$string->matches('~^\{#[a-zA-Z0-9_]+\}$~')) { - throw new DomainException($string->toString()); - } - - return new self(Name::of($string->trim('{#}')->toString())); + /** @var Maybe */ + return Maybe::just($string) + ->filter(static fn($string) => $string->matches('~^\{#[a-zA-Z0-9_]+\}$~')) + ->map(static fn($string) => $string->trim('{#}')->toString()) + ->map(Name::of(...)) + ->map(static fn($name) => new self($name)); } public function expand(Map $variables): string diff --git a/src/Expression/Level2/Reserved.php b/src/Expression/Level2/Reserved.php index 38ddb6d..10fa0c5 100644 --- a/src/Expression/Level2/Reserved.php +++ b/src/Expression/Level2/Reserved.php @@ -7,12 +7,12 @@ Expression, Expression\Name, UrlEncode, - Exception\DomainException, Exception\OnlyScalarCanBeExpandedForExpression, }; use Innmind\Immutable\{ Map, Str, + Maybe, }; /** @@ -32,13 +32,14 @@ private function __construct(Name $name) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { - if (!$string->matches('~^\{\+[a-zA-Z0-9_]+\}$~')) { - throw new DomainException($string->toString()); - } - - return new self(Name::of($string->trim('{+}')->toString())); + /** @var Maybe */ + return Maybe::just($string) + ->filter(static fn($string) => $string->matches('~^\{\+[a-zA-Z0-9_]+\}$~')) + ->map(static fn($string) => $string->trim('{+}')->toString()) + ->map(Name::of(...)) + ->map(static fn($name) => new self($name)); } /** diff --git a/src/Expression/Level3.php b/src/Expression/Level3.php index 6940029..c92e628 100644 --- a/src/Expression/Level3.php +++ b/src/Expression/Level3.php @@ -3,14 +3,12 @@ namespace Innmind\UrlTemplate\Expression; -use Innmind\UrlTemplate\{ - Expression, - Exception\DomainException, -}; +use Innmind\UrlTemplate\Expression; use Innmind\Immutable\{ Map, Sequence, Str, + Maybe, }; /** @@ -35,19 +33,18 @@ private function __construct(Sequence $names) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { - if (!$string->matches('~^\{[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { - throw new DomainException($string->toString()); - } - - return new self( - $string - ->trim('{}') - ->split(',') - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ); + /** @var Maybe */ + return Maybe::just($string) + ->filter(static fn($string) => $string->matches('~^\{[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) + ->map(static fn($string) => $string->trim('{}')->split(',')) + ->map( + static fn($names) => $names + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), + ) + ->map(static fn($names) => new self($names)); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Fragment.php b/src/Expression/Level3/Fragment.php index a9f692e..d39401a 100644 --- a/src/Expression/Level3/Fragment.php +++ b/src/Expression/Level3/Fragment.php @@ -7,12 +7,12 @@ Expression, Expression\Name, Expression\Level2, - Exception\DomainException, }; use Innmind\Immutable\{ Map, Sequence, Str, + Maybe, }; /** @@ -38,19 +38,18 @@ private function __construct(Sequence $names) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { - if (!$string->matches('~^\{#[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) { - throw new DomainException($string->toString()); - } - - return new self( - $string - ->trim('{#}') - ->split(',') - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ); + /** @var Maybe */ + return Maybe::just($string) + ->filter(static fn($string) => $string->matches('~^\{#[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) + ->map(static fn($string) => $string->trim('{#}')->split(',')) + ->map( + static fn($names) => $names + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), + ) + ->map(static fn($names) => new self($names)); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Label.php b/src/Expression/Level3/Label.php index 2ee461c..6dc5ba2 100644 --- a/src/Expression/Level3/Label.php +++ b/src/Expression/Level3/Label.php @@ -7,12 +7,12 @@ Expression, Expression\Name, Expression\Level1, - Exception\DomainException, }; use Innmind\Immutable\{ Map, Sequence, Str, + Maybe, }; /** @@ -38,19 +38,18 @@ private function __construct(Sequence $names) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { - if (!$string->matches('~^\{\.[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) { - throw new DomainException($string->toString()); - } - - return new self( - $string - ->trim('{.}') - ->split(',') - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ); + /** @var Maybe */ + return Maybe::just($string) + ->filter(static fn($string) => $string->matches('~^\{\.[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) + ->map(static fn($string) => $string->trim('{.}')->split(',')) + ->map( + static fn($names) => $names + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), + ) + ->map(static fn($names) => new self($names)); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/NamedValues.php b/src/Expression/Level3/NamedValues.php index 09cd13c..0124ab7 100644 --- a/src/Expression/Level3/NamedValues.php +++ b/src/Expression/Level3/NamedValues.php @@ -12,6 +12,7 @@ Map, Sequence, Str, + Maybe, }; /** @@ -50,7 +51,7 @@ public function __construct(string $lead, string $separator, Sequence $names) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { throw new \LogicException('should not be used directly'); } diff --git a/src/Expression/Level3/Parameters.php b/src/Expression/Level3/Parameters.php index a3ba6f7..4e80d98 100644 --- a/src/Expression/Level3/Parameters.php +++ b/src/Expression/Level3/Parameters.php @@ -6,12 +6,12 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, - Exception\DomainException, }; use Innmind\Immutable\{ Map, Sequence, Str, + Maybe, }; /** @@ -32,19 +32,18 @@ private function __construct(Sequence $names) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { - if (!$string->matches('~^\{;[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) { - throw new DomainException($string->toString()); - } - - return new self( - $string - ->trim('{;}') - ->split(',') - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ); + /** @var Maybe */ + return Maybe::just($string) + ->filter(static fn($string) => $string->matches('~^\{;[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) + ->map(static fn($string) => $string->trim('{;}')->split(',')) + ->map( + static fn($names) => $names + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), + ) + ->map(static fn($names) => new self($names)); } /** diff --git a/src/Expression/Level3/Path.php b/src/Expression/Level3/Path.php index 94efc8f..230a3da 100644 --- a/src/Expression/Level3/Path.php +++ b/src/Expression/Level3/Path.php @@ -7,12 +7,12 @@ Expression, Expression\Name, Expression\Level1, - Exception\DomainException, }; use Innmind\Immutable\{ Map, Sequence, Str, + Maybe, }; /** @@ -38,19 +38,18 @@ private function __construct(Sequence $names) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { - if (!$string->matches('~^\{/[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) { - throw new DomainException($string->toString()); - } - - return new self( - $string - ->trim('{/}') - ->split(',') - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ); + /** @var Maybe */ + return Maybe::just($string) + ->filter(static fn($string) => $string->matches('~^\{/[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) + ->map(static fn($string) => $string->trim('{/}')->split(',')) + ->map( + static fn($names) => $names + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), + ) + ->map(static fn($names) => new self($names)); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Query.php b/src/Expression/Level3/Query.php index c901142..c2b16df 100644 --- a/src/Expression/Level3/Query.php +++ b/src/Expression/Level3/Query.php @@ -6,12 +6,12 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, - Exception\DomainException, }; use Innmind\Immutable\{ Map, Sequence, Str, + Maybe, }; /** @@ -32,19 +32,18 @@ private function __construct(Sequence $names) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { - if (!$string->matches('~^\{\?[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) { - throw new DomainException($string->toString()); - } - - return new self( - $string - ->trim('{?}') - ->split(',') - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ); + /** @var Maybe */ + return Maybe::just($string) + ->filter(static fn($string) => $string->matches('~^\{\?[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) + ->map(static fn($string) => $string->trim('{?}')->split(',')) + ->map( + static fn($names) => $names + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), + ) + ->map(static fn($names) => new self($names)); } /** diff --git a/src/Expression/Level3/QueryContinuation.php b/src/Expression/Level3/QueryContinuation.php index cd98837..55db4bb 100644 --- a/src/Expression/Level3/QueryContinuation.php +++ b/src/Expression/Level3/QueryContinuation.php @@ -6,12 +6,12 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, - Exception\DomainException, }; use Innmind\Immutable\{ Map, Sequence, Str, + Maybe, }; /** @@ -32,19 +32,18 @@ private function __construct(Sequence $names) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { - if (!$string->matches('~^\{\&[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) { - throw new DomainException($string->toString()); - } - - return new self( - $string - ->trim('{&}') - ->split(',') - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ); + /** @var Maybe */ + return Maybe::just($string) + ->filter(static fn($string) => $string->matches('~^\{\&[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) + ->map(static fn($string) => $string->trim('{&}')->split(',')) + ->map( + static fn($names) => $names + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), + ) + ->map(static fn($names) => new self($names)); } public static function named(Name $name): self diff --git a/src/Expression/Level3/Reserved.php b/src/Expression/Level3/Reserved.php index c790cf0..fad6177 100644 --- a/src/Expression/Level3/Reserved.php +++ b/src/Expression/Level3/Reserved.php @@ -7,12 +7,12 @@ Expression, Expression\Name, Expression\Level2, - Exception\DomainException, }; use Innmind\Immutable\{ Map, Sequence, Str, + Maybe, }; /** @@ -38,19 +38,18 @@ private function __construct(Sequence $names) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { - if (!$string->matches('~^\{\+[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) { - throw new DomainException($string->toString()); - } - - return new self( - $string - ->trim('{+}') - ->split(',') - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ); + /** @var Maybe */ + return Maybe::just($string) + ->filter(static fn($string) => $string->matches('~^\{\+[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) + ->map(static fn($string) => $string->trim('{+}')->split(',')) + ->map( + static fn($names) => $names + ->map(static fn($name) => $name->toString()) + ->map(Name::of(...)), + ) + ->map(static fn($names) => new self($names)); } public function expand(Map $variables): string diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index 69330cf..a26ec29 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -6,12 +6,14 @@ use Innmind\UrlTemplate\{ Expression, Expression\Level4\Composite, + Exception\DomainException, Exception\ExplodeExpressionCantBeMatched, }; use Innmind\Immutable\{ Map, Str, Sequence, + Maybe, }; /** @@ -36,7 +38,7 @@ private function __construct(Name $name) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { return Level4\Parse::of( $string, @@ -83,7 +85,10 @@ public function add(Str $pattern): Composite return new Composite( ',', $this, - self::of($pattern->prepend('{')->append('}')), + self::of($pattern->prepend('{')->append('}'))->match( + static fn($expression) => $expression, + static fn() => throw new DomainException('todo'), + ), ); } diff --git a/src/Expression/Level4/Composite.php b/src/Expression/Level4/Composite.php index e358eaa..13e75e3 100644 --- a/src/Expression/Level4/Composite.php +++ b/src/Expression/Level4/Composite.php @@ -7,12 +7,12 @@ Expression, Expression\Name, Expressions, - Exception\DomainException, }; use Innmind\Immutable\{ Map, Sequence, Str, + Maybe, }; /** @@ -53,32 +53,27 @@ public static function removeLead( /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { - if (!$string->matches('~^\{[\+#\./;\?&]?[a-zA-Z0-9_]+(\*|:\d*)?(,[a-zA-Z0-9_]+(\*|:\d*)?)+\}$~')) { - throw new DomainException($string->toString()); - } - - $pieces = $string - ->trim('{}') - ->split(','); - $first = $pieces->first()->match( - static fn($first) => $first, - static fn() => throw new DomainException($string->toString()), - ); - /** - * @psalm-suppress UndefinedInterfaceMethod * @psalm-suppress MixedInferredReturnType + * @psalm-suppress MixedReturnStatement + * @psalm-suppress UndefinedInterfaceMethod */ - return $pieces - ->drop(1) - ->reduce( - Expressions::of($first->prepend('{')->append('}')), - static function(Expression $level4, Str $expression): Expression { - /** @psalm-suppress MixedReturnStatement */ - return $level4->add($expression); - }, + return Maybe::just($string) + ->filter(static fn($string) => $string->matches('~^\{[\+#\./;\?&]?[a-zA-Z0-9_]+(\*|:\d*)?(,[a-zA-Z0-9_]+(\*|:\d*)?)+\}$~')) + ->map(static fn($string) => $string->trim('{}')->split(',')) + ->flatMap( + static fn($pieces) => $pieces + ->first() + ->map(static fn($first) => $first->prepend('{')->append('}')) + ->map(Expressions::of(...)) + ->map( + static fn($first) => $pieces->drop(1)->reduce( + $first, + static fn(Expression $level4, $expression): Expression => $level4->add($expression), + ), + ), ); } diff --git a/src/Expression/Level4/Fragment.php b/src/Expression/Level4/Fragment.php index dda28f1..d92d12b 100644 --- a/src/Expression/Level4/Fragment.php +++ b/src/Expression/Level4/Fragment.php @@ -8,11 +8,13 @@ Expression\Name, Expression\Level2, Expression\Level4, + Exception\DomainException, Exception\LogicException, }; use Innmind\Immutable\{ Map, Str, + Maybe, }; /** @@ -32,7 +34,7 @@ private function __construct(Name $name) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { return Parse::of( $string, @@ -76,7 +78,10 @@ public function add(Str $pattern): Composite return Composite::removeLead( ',', $this, - self::of($pattern->prepend('{#')->append('}')), + self::of($pattern->prepend('{#')->append('}'))->match( + static fn($expression) => $expression, + static fn() => throw new DomainException('todo'), + ), ); } diff --git a/src/Expression/Level4/Label.php b/src/Expression/Level4/Label.php index a9e9561..5b92af2 100644 --- a/src/Expression/Level4/Label.php +++ b/src/Expression/Level4/Label.php @@ -8,10 +8,12 @@ Expression\Name, Expression\Level1, Expression\Level4, + Exception\DomainException, }; use Innmind\Immutable\{ Map, Str, + Maybe, }; /** @@ -29,7 +31,7 @@ private function __construct(Name $name) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { return Parse::of( $string, @@ -71,7 +73,10 @@ public function add(Str $pattern): Composite return new Composite( '', $this, - self::of($pattern->prepend('{.')->append('}')), + self::of($pattern->prepend('{.')->append('}'))->match( + static fn($expression) => $expression, + static fn() => throw new DomainException('todo'), + ), ); } diff --git a/src/Expression/Level4/Parameters.php b/src/Expression/Level4/Parameters.php index bf1dd0a..ffbabab 100644 --- a/src/Expression/Level4/Parameters.php +++ b/src/Expression/Level4/Parameters.php @@ -9,12 +9,14 @@ Expression\Level1, Expression\Level3, Expression\Level4, + Exception\DomainException, Exception\ExplodeExpressionCantBeMatched, }; use Innmind\Immutable\{ Map, Str, Sequence, + Maybe, }; /** @@ -37,7 +39,7 @@ private function __construct(Name $name) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { return Parse::of( $string, @@ -77,7 +79,10 @@ public function add(Str $pattern): Composite return new Composite( '', $this, - self::of($pattern->prepend('{;')->append('}')), + self::of($pattern->prepend('{;')->append('}'))->match( + static fn($expression) => $expression, + static fn() => throw new DomainException('todo'), + ), ); } diff --git a/src/Expression/Level4/Parse.php b/src/Expression/Level4/Parse.php index 72bd85c..a2e8696 100644 --- a/src/Expression/Level4/Parse.php +++ b/src/Expression/Level4/Parse.php @@ -6,23 +6,23 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, - Exception\DomainException, - Exception\ExpressionLimitCantBeNegative, }; -use Innmind\Immutable\Str; +use Innmind\Immutable\{ + Str, + Maybe, +}; final class Parse { /** * @psalm-pure - * @template T of Expression * - * @param pure-callable(Name): T $standard - * @param pure-callable(Name): T $explode - * @param pure-callable(Name, positive-int): T $limit + * @param pure-callable(Name): Expression $standard + * @param pure-callable(Name): Expression $explode + * @param pure-callable(Name, positive-int): Expression $limit * @param non-empty-string|null $lead * - * @return T + * @return Maybe */ public static function of( Str $string, @@ -30,7 +30,7 @@ public static function of( callable $explode, callable $limit, string $lead = null, - ): Expression { + ): Maybe { $drop = match ($lead) { null => 1, default => 2, @@ -40,27 +40,67 @@ public static function of( default => "\\$lead", }; - if ($string->matches("~^\{{$lead}[a-zA-Z0-9_]+\}\$~")) { - return $standard(Name::of($string->drop($drop)->dropEnd(1)->toString())); - } - - if ($string->matches("~^\{{$lead}[a-zA-Z0-9_]+\*\}\$~")) { - return $explode(Name::of($string->drop($drop)->dropEnd(2)->toString())); - } - - if ($string->matches("~^\{{$lead}[a-zA-Z0-9_]+:\d+\}\$~")) { - $string = $string->drop($drop)->dropEnd(1); - [$name, $int] = $string->split(':')->toList(); - $int = (int) $int->toString(); - - if ($int < 1) { - throw new ExpressionLimitCantBeNegative($int); - } + return Maybe::just($string) + ->filter(static fn($string) => $string->matches("~^\{{$lead}[a-zA-Z0-9_]+\}\$~")) + ->map(static fn($string) => $string->drop($drop)->dropEnd(1)->toString()) + ->map(Name::of(...)) + ->map($standard) + ->otherwise(static fn() => self::explode($string, $explode, $lead, $drop)) + ->otherwise(static fn() => self::limit($string, $limit, $lead, $drop)); + } - /** @psalm-suppress ArgumentTypeCoercion */ - return $limit(Name::of($name->toString()), $int); - } + /** + * @psalm-pure + * + * @param pure-callable(Name): Expression $explode + * @param positive-int $drop + * + * @return Maybe + */ + private static function explode( + Str $string, + callable $explode, + string $lead, + int $drop, + ): Maybe { + return Maybe::just($string) + ->filter(static fn($string) => $string->matches("~^\{{$lead}[a-zA-Z0-9_]+\*\}\$~")) + ->map(static fn($string) => $string->drop($drop)->dropEnd(2)->toString()) + ->map(Name::of(...)) + ->map($explode); + } - throw new DomainException($string->toString()); + /** + * @psalm-pure + * + * @param pure-callable(Name, positive-int): Expression $limit + * @param positive-int $drop + * + * @return Maybe + */ + private static function limit( + Str $string, + callable $limit, + string $lead, + int $drop, + ): Maybe { + /** @psalm-suppress ArgumentTypeCoercion For the positive-int */ + return Maybe::just($string) + ->filter(static fn($string) => $string->matches("~^\{{$lead}[a-zA-Z0-9_]+:\d+\}\$~")) + ->map(static fn($string) => $string->drop($drop)->dropEnd(1)->split(':')) + ->map(static fn($pieces) => $pieces->map(static fn($piece) => $piece->toString())) + ->flatMap( + static fn($pieces) => $pieces + ->first() + ->map(Name::of(...)) + ->flatMap( + static fn($name) => $pieces + ->last() + ->filter(\is_numeric(...)) + ->map(static fn($limit) => (int) $limit) + ->filter(static fn(int $limit) => $limit > 0) + ->map(static fn($int) => $limit($name, $int)), + ), + ); } } diff --git a/src/Expression/Level4/Path.php b/src/Expression/Level4/Path.php index 41a76ab..3065c28 100644 --- a/src/Expression/Level4/Path.php +++ b/src/Expression/Level4/Path.php @@ -8,10 +8,12 @@ Expression\Name, Expression\Level1, Expression\Level4, + Exception\DomainException, }; use Innmind\Immutable\{ Map, Str, + Maybe, }; /** @@ -29,7 +31,7 @@ private function __construct(Name $name) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { return Parse::of( $string, @@ -71,7 +73,10 @@ public function add(Str $pattern): Composite return new Composite( '', $this, - self::of($pattern->prepend('{/')->append('}')), + self::of($pattern->prepend('{/')->append('}'))->match( + static fn($expression) => $expression, + static fn() => throw new DomainException('todo'), + ), ); } diff --git a/src/Expression/Level4/Query.php b/src/Expression/Level4/Query.php index e6bf1a1..3f337e1 100644 --- a/src/Expression/Level4/Query.php +++ b/src/Expression/Level4/Query.php @@ -9,12 +9,14 @@ Expression\Level1, Expression\Level3, Expression\Level4, + Exception\DomainException, Exception\ExplodeExpressionCantBeMatched, }; use Innmind\Immutable\{ Map, Str, Sequence, + Maybe, }; /** @@ -37,7 +39,7 @@ private function __construct(Name $name) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { return Parse::of( $string, @@ -77,7 +79,10 @@ public function add(Str $pattern): Composite return new Composite( '', $this, - QueryContinuation::of($pattern->prepend('{&')->append('}')), + QueryContinuation::of($pattern->prepend('{&')->append('}'))->match( + static fn($expression) => $expression, + static fn() => throw new DomainException('todo'), + ), ); } diff --git a/src/Expression/Level4/QueryContinuation.php b/src/Expression/Level4/QueryContinuation.php index de71f4b..b18998b 100644 --- a/src/Expression/Level4/QueryContinuation.php +++ b/src/Expression/Level4/QueryContinuation.php @@ -9,12 +9,14 @@ Expression\Level1, Expression\Level3, Expression\Level4, + Exception\DomainException, Exception\ExplodeExpressionCantBeMatched, }; use Innmind\Immutable\{ Map, Str, Sequence, + Maybe, }; /** @@ -37,7 +39,7 @@ private function __construct(Name $name) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { return Parse::of( $string, @@ -77,7 +79,10 @@ public function add(Str $pattern): Composite return new Composite( '', $this, - self::of($pattern->prepend('{&')->append('}')), + self::of($pattern->prepend('{&')->append('}'))->match( + static fn($expression) => $expression, + static fn() => throw new DomainException('todo'), + ), ); } diff --git a/src/Expression/Level4/Reserved.php b/src/Expression/Level4/Reserved.php index 56ee16c..03985ba 100644 --- a/src/Expression/Level4/Reserved.php +++ b/src/Expression/Level4/Reserved.php @@ -8,11 +8,13 @@ Expression\Name, Expression\Level2, Expression\Level4, + Exception\DomainException, Exception\ExplodeExpressionCantBeMatched, }; use Innmind\Immutable\{ Map, Str, + Maybe, }; /** @@ -37,7 +39,7 @@ private function __construct(Name $name) /** * @psalm-pure */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { return Parse::of( $string, @@ -83,7 +85,10 @@ public function add(Str $pattern): Composite return new Composite( ',', $this, - self::of($pattern->prepend('{+')->append('}')), + self::of($pattern->prepend('{+')->append('}'))->match( + static fn($expression) => $expression, + static fn() => throw new DomainException('todo'), + ), ); } diff --git a/src/Expressions.php b/src/Expressions.php index 44dad23..ed45e5c 100644 --- a/src/Expressions.php +++ b/src/Expressions.php @@ -7,6 +7,7 @@ use Innmind\Immutable\{ Sequence, Str, + Maybe, }; /** @@ -19,43 +20,46 @@ final class Expressions */ public static function of(Str $string): Expression { - foreach (self::expressions() as $expression) { - try { - /** @var Expression */ - return [$expression, 'of']($string); - } catch (DomainException $e) { - //pass - } - } - - throw new DomainException($string->toString()); + /** @psalm-suppress MixedArgumentTypeCoercion */ + return self::expressions() + ->reduce( + Maybe::nothing(), + static fn(Maybe $expression, $attempt) => $expression->otherwise( + static fn() => $attempt($string), + ), + ) + ->match( + static fn(Expression $expression): Expression => $expression, + static fn() => throw new DomainException($string->toString()), + ); } /** * @psalm-pure * - * @return list> + * @return Sequence> */ - private static function expressions(): array + private static function expressions(): Sequence { - return [ - Expression\Level4::class, - Expression\Level4\Reserved::class, - Expression\Level4\Fragment::class, - Expression\Level4\Label::class, - Expression\Level4\Path::class, - Expression\Level4\Parameters::class, - Expression\Level4\Query::class, - Expression\Level4\QueryContinuation::class, - Expression\Level3::class, - Expression\Level3\Reserved::class, - Expression\Level3\Fragment::class, - Expression\Level3\Label::class, - Expression\Level3\Path::class, - Expression\Level3\Parameters::class, - Expression\Level3\Query::class, - Expression\Level3\QueryContinuation::class, - Expression\Level4\Composite::class, - ]; + /** @var Sequence> */ + return Sequence::of( + Expression\Level4::of(...), + Expression\Level4\Reserved::of(...), + Expression\Level4\Fragment::of(...), + Expression\Level4\Label::of(...), + Expression\Level4\Path::of(...), + Expression\Level4\Parameters::of(...), + Expression\Level4\Query::of(...), + Expression\Level4\QueryContinuation::of(...), + Expression\Level3::of(...), + Expression\Level3\Reserved::of(...), + Expression\Level3\Fragment::of(...), + Expression\Level3\Label::of(...), + Expression\Level3\Path::of(...), + Expression\Level3\Parameters::of(...), + Expression\Level3\Query::of(...), + Expression\Level3\QueryContinuation::of(...), + Expression\Level4\Composite::of(...), + ); } } diff --git a/tests/Expression/Level1Test.php b/tests/Expression/Level1Test.php index 2605bcf..9c9d258 100644 --- a/tests/Expression/Level1Test.php +++ b/tests/Expression/Level1Test.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level1, Expression, - Exception\DomainException, Exception\OnlyScalarCanBeExpandedForExpression, }; use Innmind\Immutable\{ @@ -21,18 +20,30 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Level1::of(Str::of('{foo}')), + Level1::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } public function testStringCast() { - $this->assertSame('{foo}', Level1::of(Str::of('{foo}'))->toString()); + $this->assertSame( + '{foo}', + Level1::of(Str::of('{foo}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); } public function testExpand() { - $expression = Level1::of(Str::of('{foo}')); + $expression = Level1::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ); $this->assertSame('value', $expression->expand( Map::of(['foo', 'value']), @@ -49,30 +60,39 @@ public function testOf() { $this->assertInstanceOf( Level1::class, - $expression = Level1::of(Str::of('{foo}')), + $expression = Level1::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{foo}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('foo'); - - Level1::of(Str::of('foo')); + $this->assertNull(Level1::of(Str::of('foo'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testRegex() { $this->assertSame( '(?[a-zA-Z0-9\%\-\.\_\~]*)', - Level1::of(Str::of('{foo}'))->regex(), + Level1::of(Str::of('{foo}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } public function testThrowWhenTryingToExpandWithAnArray() { - $expression = Level1::of(Str::of('{foo}')); + $expression = Level1::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ); $this->expectException(OnlyScalarCanBeExpandedForExpression::class); $this->expectExceptionMessage('foo'); diff --git a/tests/Expression/Level2/FragmentTest.php b/tests/Expression/Level2/FragmentTest.php index ab553c3..ec41157 100644 --- a/tests/Expression/Level2/FragmentTest.php +++ b/tests/Expression/Level2/FragmentTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level2\Fragment, Expression, - Exception\DomainException, Exception\OnlyScalarCanBeExpandedForExpression, }; use Innmind\Immutable\{ @@ -21,18 +20,30 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Fragment::of(Str::of('{#foo}')), + Fragment::of(Str::of('{#foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } public function testStringCast() { - $this->assertSame('{#foo}', Fragment::of(Str::of('{#foo}'))->toString()); + $this->assertSame( + '{#foo}', + Fragment::of(Str::of('{#foo}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); } public function testExpand() { - $expression = Fragment::of(Str::of('{#foo}')); + $expression = Fragment::of(Str::of('{#foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ); $this->assertSame('#value', $expression->expand( Map::of(['foo', 'value']), @@ -52,30 +63,39 @@ public function testOf() { $this->assertInstanceOf( Fragment::class, - $expression = Fragment::of(Str::of('{#foo}')), + $expression = Fragment::of(Str::of('{#foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{#foo}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('foo'); - - Fragment::of(Str::of('foo')); + $this->assertNull(Fragment::of(Str::of('foo'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testRegex() { $this->assertSame( '\#(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)', - Fragment::of(Str::of('{#foo}'))->regex(), + Fragment::of(Str::of('{#foo}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } public function testThrowWhenTryingToExpandWithAnArray() { - $expression = Fragment::of(Str::of('{#foo}')); + $expression = Fragment::of(Str::of('{#foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ); $this->expectException(OnlyScalarCanBeExpandedForExpression::class); $this->expectExceptionMessage('foo'); diff --git a/tests/Expression/Level2/ReservedTest.php b/tests/Expression/Level2/ReservedTest.php index 2e76fb0..3094cb8 100644 --- a/tests/Expression/Level2/ReservedTest.php +++ b/tests/Expression/Level2/ReservedTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level2\Reserved, Expression, - Exception\DomainException, Exception\OnlyScalarCanBeExpandedForExpression, }; use Innmind\Immutable\{ @@ -21,18 +20,30 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Reserved::of(Str::of('{+foo}')), + Reserved::of(Str::of('{+foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } public function testStringCast() { - $this->assertSame('{+foo}', Reserved::of(Str::of('{+foo}'))->toString()); + $this->assertSame( + '{+foo}', + Reserved::of(Str::of('{+foo}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); } public function testExpand() { - $expression = Reserved::of(Str::of('{+foo}')); + $expression = Reserved::of(Str::of('{+foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ); $this->assertSame('value', $expression->expand( Map::of(['foo', 'value']), @@ -52,30 +63,39 @@ public function testOf() { $this->assertInstanceOf( Reserved::class, - $expression = Reserved::of(Str::of('{+foo}')), + $expression = Reserved::of(Str::of('{+foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{+foo}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('foo'); - - Reserved::of(Str::of('foo')); + $this->assertNull(Reserved::of(Str::of('foo'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testRegex() { $this->assertSame( '(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)', - Reserved::of(Str::of('{+foo}'))->regex(), + Reserved::of(Str::of('{+foo}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } public function testThrowWhenTryingToExpandWithAnArray() { - $expression = Reserved::of(Str::of('{+foo}')); + $expression = Reserved::of(Str::of('{+foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ); $this->expectException(OnlyScalarCanBeExpandedForExpression::class); $this->expectExceptionMessage('foo'); diff --git a/tests/Expression/Level3/FragmentTest.php b/tests/Expression/Level3/FragmentTest.php index d960e10..caa9ec8 100644 --- a/tests/Expression/Level3/FragmentTest.php +++ b/tests/Expression/Level3/FragmentTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level3\Fragment, Expression, - Exception\DomainException, }; use Innmind\Immutable\{ Map, @@ -20,7 +19,10 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Fragment::of(Str::of('{#foo,bar}')), + Fragment::of(Str::of('{#foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } @@ -28,7 +30,10 @@ public function testStringCast() { $this->assertSame( '{#foo,bar}', - Fragment::of(Str::of('{#foo,bar}'))->toString(), + Fragment::of(Str::of('{#foo,bar}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), ); } @@ -44,11 +49,17 @@ public function testExpand() $this->assertSame( '#1024,Hello%20World!,768', - Fragment::of(Str::of('{#x,hello,y}'))->expand($variables), + Fragment::of(Str::of('{#x,hello,y}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '#/foo/bar,1024', - Fragment::of(Str::of('{#path,x}'))->expand($variables), + Fragment::of(Str::of('{#path,x}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -56,24 +67,30 @@ public function testOf() { $this->assertInstanceOf( Fragment::class, - $expression = Fragment::of(Str::of('{#foo,bar}')), + $expression = Fragment::of(Str::of('{#foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{#foo,bar}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{foo}'); - - Fragment::of(Str::of('{foo}')); + $this->assertNull(Fragment::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testRegex() { $this->assertSame( '\#(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*),(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)', - Fragment::of(Str::of('{#foo,bar}'))->regex(), + Fragment::of(Str::of('{#foo,bar}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level3/LabelTest.php b/tests/Expression/Level3/LabelTest.php index 8acebef..4379970 100644 --- a/tests/Expression/Level3/LabelTest.php +++ b/tests/Expression/Level3/LabelTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level3\Label, Expression, - Exception\DomainException, }; use Innmind\Immutable\{ Map, @@ -20,7 +19,10 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Label::of(Str::of('{.foo,bar}')), + Label::of(Str::of('{.foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } @@ -28,7 +30,10 @@ public function testStringCast() { $this->assertSame( '{.foo,bar}', - Label::of(Str::of('{.foo,bar}'))->toString(), + Label::of(Str::of('{.foo,bar}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), ); } @@ -44,11 +49,17 @@ public function testExpand() $this->assertSame( '.1024.768', - Label::of(Str::of('{.x,y}'))->expand($variables), + Label::of(Str::of('{.x,y}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '.value', - Label::of(Str::of('{.var}'))->expand($variables), + Label::of(Str::of('{.var}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -56,24 +67,30 @@ public function testOf() { $this->assertInstanceOf( Label::class, - $expression = Label::of(Str::of('{.foo,bar}')), + $expression = Label::of(Str::of('{.foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{.foo,bar}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{foo}'); - - Label::of(Str::of('{foo}')); + $this->assertNull(Label::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testRegex() { $this->assertSame( '\.(?[a-zA-Z0-9\%\-\_\~]*).(?[a-zA-Z0-9\%\-\_\~]*)', - Label::of(Str::of('{.foo,bar}'))->regex(), + Label::of(Str::of('{.foo,bar}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level3/ParametersTest.php b/tests/Expression/Level3/ParametersTest.php index 0edc133..2d8f9d0 100644 --- a/tests/Expression/Level3/ParametersTest.php +++ b/tests/Expression/Level3/ParametersTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level3\Parameters, Expression, - Exception\DomainException, }; use Innmind\Immutable\{ Map, @@ -20,7 +19,10 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Parameters::of(Str::of('{;foo,bar}')), + Parameters::of(Str::of('{;foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } @@ -28,7 +30,10 @@ public function testStringCast() { $this->assertSame( '{;foo,bar}', - Parameters::of(Str::of('{;foo,bar}'))->toString(), + Parameters::of(Str::of('{;foo,bar}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), ); } @@ -44,11 +49,17 @@ public function testExpand() $this->assertSame( ';x=1024;y=768', - Parameters::of(Str::of('{;x,y}'))->expand($variables), + Parameters::of(Str::of('{;x,y}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( ';x=1024;y=768;empty', - Parameters::of(Str::of('{;x,y,empty}'))->expand($variables), + Parameters::of(Str::of('{;x,y,empty}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -56,24 +67,30 @@ public function testOf() { $this->assertInstanceOf( Parameters::class, - $expression = Parameters::of(Str::of('{;foo,bar}')), + $expression = Parameters::of(Str::of('{;foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{;foo,bar}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{;foo}'); - - Parameters::of(Str::of('{;foo}')); + $this->assertNull(Parameters::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testRegex() { $this->assertSame( '\;foo=?(?[a-zA-Z0-9\%\-\.\_\~]*)\;bar=?(?[a-zA-Z0-9\%\-\.\_\~]*)', - Parameters::of(Str::of('{;foo,bar}'))->regex(), + Parameters::of(Str::of('{;foo,bar}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level3/PathTest.php b/tests/Expression/Level3/PathTest.php index ee9bd64..71bae63 100644 --- a/tests/Expression/Level3/PathTest.php +++ b/tests/Expression/Level3/PathTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level3\Path, Expression, - Exception\DomainException, }; use Innmind\Immutable\{ Map, @@ -20,7 +19,10 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Path::of(Str::of('{/foo,bar}')), + Path::of(Str::of('{/foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } @@ -28,7 +30,10 @@ public function testStringCast() { $this->assertSame( '{/foo,bar}', - Path::of(Str::of('{/foo,bar}'))->toString(), + Path::of(Str::of('{/foo,bar}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), ); } @@ -44,11 +49,17 @@ public function testExpand() $this->assertSame( '/value', - Path::of(Str::of('{/var}'))->expand($variables), + Path::of(Str::of('{/var}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '/value/1024', - Path::of(Str::of('{/var,x}'))->expand($variables), + Path::of(Str::of('{/var,x}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -56,24 +67,30 @@ public function testOf() { $this->assertInstanceOf( Path::class, - $expression = Path::of(Str::of('{/foo,bar}')), + $expression = Path::of(Str::of('{/foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{/foo,bar}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{foo}'); - - Path::of(Str::of('{foo}')); + $this->assertNull(Path::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testRegex() { $this->assertSame( '/(?[a-zA-Z0-9\%\-\.\_\~]*)/(?[a-zA-Z0-9\%\-\.\_\~]*)', - Path::of(Str::of('{/foo,bar}'))->regex(), + Path::of(Str::of('{/foo,bar}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level3/QueryContinuationTest.php b/tests/Expression/Level3/QueryContinuationTest.php index dfc6796..56d3315 100644 --- a/tests/Expression/Level3/QueryContinuationTest.php +++ b/tests/Expression/Level3/QueryContinuationTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level3\QueryContinuation, Expression, - Exception\DomainException, }; use Innmind\Immutable\{ Map, @@ -20,7 +19,10 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - QueryContinuation::of(Str::of('{&foo,bar}')), + QueryContinuation::of(Str::of('{&foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } @@ -28,7 +30,10 @@ public function testStringCast() { $this->assertSame( '{&foo,bar}', - QueryContinuation::of(Str::of('{&foo,bar}'))->toString(), + QueryContinuation::of(Str::of('{&foo,bar}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), ); } @@ -44,11 +49,17 @@ public function testExpand() $this->assertSame( '&x=1024&y=768', - QueryContinuation::of(Str::of('{&x,y}'))->expand($variables), + QueryContinuation::of(Str::of('{&x,y}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '&x=1024&y=768&empty=', - QueryContinuation::of(Str::of('{&x,y,empty}'))->expand($variables), + QueryContinuation::of(Str::of('{&x,y,empty}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -56,24 +67,30 @@ public function testOf() { $this->assertInstanceOf( QueryContinuation::class, - $expression = QueryContinuation::of(Str::of('{&foo,bar}')), + $expression = QueryContinuation::of(Str::of('{&foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{&foo,bar}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{foo}'); - - QueryContinuation::of(Str::of('{foo}')); + $this->assertNull(QueryContinuation::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testRegex() { $this->assertSame( '\&foo=(?[a-zA-Z0-9\%\-\.\_\~]*)\&bar=(?[a-zA-Z0-9\%\-\.\_\~]*)', - QueryContinuation::of(Str::of('{&foo,bar}'))->regex(), + QueryContinuation::of(Str::of('{&foo,bar}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level3/QueryTest.php b/tests/Expression/Level3/QueryTest.php index 8114082..ddc4dae 100644 --- a/tests/Expression/Level3/QueryTest.php +++ b/tests/Expression/Level3/QueryTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level3\Query, Expression, - Exception\DomainException, }; use Innmind\Immutable\{ Map, @@ -20,7 +19,10 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Query::of(Str::of('{?foo,bar}')), + Query::of(Str::of('{?foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } @@ -28,7 +30,10 @@ public function testStringCast() { $this->assertSame( '{?foo,bar}', - Query::of(Str::of('{?foo,bar}'))->toString(), + Query::of(Str::of('{?foo,bar}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), ); } @@ -44,11 +49,17 @@ public function testExpand() $this->assertSame( '?x=1024&y=768', - Query::of(Str::of('{?x,y}'))->expand($variables), + Query::of(Str::of('{?x,y}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '?x=1024&y=768&empty=', - Query::of(Str::of('{?x,y,empty}'))->expand($variables), + Query::of(Str::of('{?x,y,empty}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -56,24 +67,30 @@ public function testOf() { $this->assertInstanceOf( Query::class, - $expression = Query::of(Str::of('{?foo,bar}')), + $expression = Query::of(Str::of('{?foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{?foo,bar}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{foo}'); - - Query::of(Str::of('{foo}')); + $this->assertNull(Query::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testRegex() { $this->assertSame( '\?foo=(?[a-zA-Z0-9\%\-\.\_\~]*)\&bar=(?[a-zA-Z0-9\%\-\.\_\~]*)', - Query::of(Str::of('{?foo,bar}'))->regex(), + Query::of(Str::of('{?foo,bar}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level3/ReservedTest.php b/tests/Expression/Level3/ReservedTest.php index a847269..b89b3bd 100644 --- a/tests/Expression/Level3/ReservedTest.php +++ b/tests/Expression/Level3/ReservedTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level3\Reserved, Expression, - Exception\DomainException, }; use Innmind\Immutable\{ Map, @@ -20,7 +19,10 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Reserved::of(Str::of('{+foo,bar}')), + Reserved::of(Str::of('{+foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } @@ -28,7 +30,10 @@ public function testStringCast() { $this->assertSame( '{+foo,bar}', - Reserved::of(Str::of('{+foo,bar}'))->toString(), + Reserved::of(Str::of('{+foo,bar}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), ); } @@ -44,11 +49,17 @@ public function testExpand() $this->assertSame( '1024,Hello%20World!,768', - Reserved::of(Str::of('{+x,hello,y}'))->expand($variables), + Reserved::of(Str::of('{+x,hello,y}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '/foo/bar,1024', - Reserved::of(Str::of('{+path,x}'))->expand($variables), + Reserved::of(Str::of('{+path,x}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -56,24 +67,30 @@ public function testOf() { $this->assertInstanceOf( Reserved::class, - $expression = Reserved::of(Str::of('{+foo,bar}')), + $expression = Reserved::of(Str::of('{+foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{+foo,bar}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{foo}'); - - Reserved::of(Str::of('{foo}')); + $this->assertNull(Reserved::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testRegex() { $this->assertSame( '(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*),(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)', - Reserved::of(Str::of('{+foo,bar}'))->regex(), + Reserved::of(Str::of('{+foo,bar}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level3Test.php b/tests/Expression/Level3Test.php index 10bca08..a1f8eff 100644 --- a/tests/Expression/Level3Test.php +++ b/tests/Expression/Level3Test.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level3, Expression, - Exception\DomainException, }; use Innmind\Immutable\{ Map, @@ -20,7 +19,10 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Level3::of(Str::of('{foo,bar}')), + Level3::of(Str::of('{foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } @@ -28,7 +30,10 @@ public function testStringCast() { $this->assertSame( '{foo,bar}', - Level3::of(Str::of('{foo,bar}'))->toString(), + Level3::of(Str::of('{foo,bar}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), ); } @@ -44,11 +49,17 @@ public function testExpand() $this->assertSame( '1024,768', - Level3::of(Str::of('{x,y}'))->expand($variables), + Level3::of(Str::of('{x,y}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '1024,Hello%20World%21,768', - Level3::of(Str::of('{x,hello,y}'))->expand($variables), + Level3::of(Str::of('{x,hello,y}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -56,24 +67,30 @@ public function testOf() { $this->assertInstanceOf( Level3::class, - $expression = Level3::of(Str::of('{foo,bar}')), + $expression = Level3::of(Str::of('{foo,bar}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{foo,bar}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{foo}'); - - Level3::of(Str::of('{foo}')); + $this->assertNull(Level3::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testRegex() { $this->assertSame( '(?[a-zA-Z0-9\%\-\.\_\~]*),(?[a-zA-Z0-9\%\-\.\_\~]*)', - Level3::of(Str::of('{foo,bar}'))->regex(), + Level3::of(Str::of('{foo,bar}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level4/CompositeTest.php b/tests/Expression/Level4/CompositeTest.php index e742ed9..618a162 100644 --- a/tests/Expression/Level4/CompositeTest.php +++ b/tests/Expression/Level4/CompositeTest.php @@ -8,7 +8,6 @@ Expression\Level4\Path, Expression\Level4, Expression, - Exception\DomainException, }; use Innmind\Immutable\{ Map, @@ -35,16 +34,28 @@ public function testStringCast() '{/var:1,var}', (new Composite( '/', - Path::of(Str::of('{/var:1}')), - Level4::of(Str::of('{var}')), + Path::of(Str::of('{/var:1}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), + Level4::of(Str::of('{var}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ))->toString(), ); $this->assertSame( '{/list*,path:4}', (new Composite( '/', - Path::of(Str::of('{/list*}')), - Level4::of(Str::of('{path:4}')), + Path::of(Str::of('{/list*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), + Level4::of(Str::of('{path:4}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ))->toString(), ); } @@ -62,16 +73,28 @@ public function testExpand() '/v/value', (new Composite( '/', - Path::of(Str::of('{/var:1}')), - Level4::of(Str::of('{var}')), + Path::of(Str::of('{/var:1}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), + Level4::of(Str::of('{var}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ))->expand($variables), ); $this->assertSame( '/red/green/blue/%2Ffoo', (new Composite( '/', - Path::of(Str::of('{/list*}')), - Level4::of(Str::of('{path:4}')), + Path::of(Str::of('{/list*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), + Level4::of(Str::of('{path:4}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ))->expand($variables), ); } @@ -88,57 +111,87 @@ public function testOf($pattern, $expected) ('list', ['red', 'green', 'blue']) ('keys', [['semi', ';'], ['dot', '.'], ['comma', ',']]); - $expression = Composite::of(Str::of($pattern)); + $expression = Composite::of(Str::of($pattern))->match( + static fn($expression) => $expression, + static fn() => null, + ); $this->assertSame($pattern, $expression->toString()); $this->assertSame($expected, $expression->expand($variables)); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('foo'); - - Composite::of(Str::of('foo')); + $this->assertNull(Composite::of(Str::of('foo'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testRegex() { $this->assertSame( '(?[a-zA-Z0-9\%\-\.\_\~]*)\,(?[a-zA-Z0-9\%\-\.\_\~]*)', - Composite::of(Str::of('{var,hello}'))->regex(), + Composite::of(Str::of('{var,hello}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '(?[a-zA-Z0-9\%\-\.\_\~]*)\,(?[a-zA-Z0-9\%\-\.\_\~]{5})', - Composite::of(Str::of('{var,hello:5}'))->regex(), + Composite::of(Str::of('{var,hello:5}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)\,(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]{5})', - Composite::of(Str::of('{+var,hello:5}'))->regex(), + Composite::of(Str::of('{+var,hello:5}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '\#(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)\,(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]{5})', - Composite::of(Str::of('{#var,hello:5}'))->regex(), + Composite::of(Str::of('{#var,hello:5}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '\.(?[a-zA-Z0-9\%\-\.\_\~]*)\.(?[a-zA-Z0-9\%\-\.\_\~]{5})', - Composite::of(Str::of('{.var,hello:5}'))->regex(), + Composite::of(Str::of('{.var,hello:5}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '\/(?[a-zA-Z0-9\%\-\.\_\~]*)\/(?[a-zA-Z0-9\%\-\.\_\~]{5})', - Composite::of(Str::of('{/var,hello:5}'))->regex(), + Composite::of(Str::of('{/var,hello:5}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '\;var=(?[a-zA-Z0-9\%\-\.\_\~]*)\;hello=(?[a-zA-Z0-9\%\-\.\_\~]{5})', - Composite::of(Str::of('{;var,hello:5}'))->regex(), + Composite::of(Str::of('{;var,hello:5}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '\?var=(?[a-zA-Z0-9\%\-\.\_\~]*)\&hello=(?[a-zA-Z0-9\%\-\.\_\~]{5})', - Composite::of(Str::of('{?var,hello:5}'))->regex(), + Composite::of(Str::of('{?var,hello:5}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '\&var=(?[a-zA-Z0-9\%\-\.\_\~]*)\&hello=(?[a-zA-Z0-9\%\-\.\_\~]{5})', - Composite::of(Str::of('{&var,hello:5}'))->regex(), + Composite::of(Str::of('{&var,hello:5}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } diff --git a/tests/Expression/Level4/FragmentTest.php b/tests/Expression/Level4/FragmentTest.php index 833f564..9a18c9f 100644 --- a/tests/Expression/Level4/FragmentTest.php +++ b/tests/Expression/Level4/FragmentTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level4\Fragment, Expression, - Exception\DomainException, Exception\LogicException, }; use Innmind\Immutable\{ @@ -27,33 +26,61 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Fragment::of(Str::of('{#foo}')), + Fragment::of(Str::of('{#foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - Fragment::of(Str::of('{#foo*}')), + Fragment::of(Str::of('{#foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - Fragment::of(Str::of('{#foo:42}')), + Fragment::of(Str::of('{#foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } public function testStringCast() { - $this->assertSame('{#foo}', Fragment::of(Str::of('{#foo}'))->toString()); - $this->assertSame('{#foo*}', Fragment::of(Str::of('{#foo*}'))->toString()); - $this->assertSame('{#foo:42}', Fragment::of(Str::of('{#foo:42}'))->toString()); + $this->assertSame( + '{#foo}', + Fragment::of(Str::of('{#foo}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{#foo*}', + Fragment::of(Str::of('{#foo*}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{#foo:42}', + Fragment::of(Str::of('{#foo:42}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); } - public function testThrowWhenNegativeLimit() + public function testReturnNothingWhenNegativeLimit() { $this ->forAll(Set\Integers::below(1)) ->then(function(int $int): void { - $this->expectException(DomainException::class); - - Fragment::of(Str::of("{#list:$int}")); + $this->assertNull(Fragment::of(Str::of("{#list:$int}"))->match( + static fn($expression) => $expression, + static fn() => null, + )); }); } @@ -68,23 +95,38 @@ public function testExpand() $this->assertSame( '#/foo/b', - Fragment::of(Str::of('{#path:6}'))->expand($variables), + Fragment::of(Str::of('{#path:6}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '#red,green,blue', - Fragment::of(Str::of('{#list}'))->expand($variables), + Fragment::of(Str::of('{#list}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '#red,green,blue', - Fragment::of(Str::of('{#list*}'))->expand($variables), + Fragment::of(Str::of('{#list*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '#semi,;,dot,.,comma,,', - Fragment::of(Str::of('{#keys}'))->expand($variables), + Fragment::of(Str::of('{#keys}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '#semi=;,dot=.,comma=,', - Fragment::of(Str::of('{#keys*}'))->expand($variables), + Fragment::of(Str::of('{#keys*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -92,45 +134,63 @@ public function testOf() { $this->assertInstanceOf( Fragment::class, - $expression = Fragment::of(Str::of('{#foo}')), + $expression = Fragment::of(Str::of('{#foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{#foo}', $expression->toString()); $this->assertInstanceOf( Fragment::class, - $expression = Fragment::of(Str::of('{#foo*}')), + $expression = Fragment::of(Str::of('{#foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{#foo*}', $expression->toString()); $this->assertInstanceOf( Fragment::class, - $expression = Fragment::of(Str::of('{#foo:42}')), + $expression = Fragment::of(Str::of('{#foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{#foo:42}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{foo}'); - - Fragment::of(Str::of('{foo}')); + $this->assertNull(Fragment::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testThrowExplodeRegex() { $this->expectException(LogicException::class); - Fragment::of(Str::of('{#foo*}'))->regex(); + Fragment::of(Str::of('{#foo*}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ); } public function testRegex() { $this->assertSame( '\#(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)', - Fragment::of(Str::of('{#foo}'))->regex(), + Fragment::of(Str::of('{#foo}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '\#(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]{2})', - Fragment::of(Str::of('{#foo:2}'))->regex(), + Fragment::of(Str::of('{#foo:2}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level4/LabelTest.php b/tests/Expression/Level4/LabelTest.php index b152f04..099843b 100644 --- a/tests/Expression/Level4/LabelTest.php +++ b/tests/Expression/Level4/LabelTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level4\Label, Expression, - Exception\DomainException, Exception\LogicException, }; use Innmind\Immutable\{ @@ -27,33 +26,61 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Label::of(Str::of('{.foo}')), + Label::of(Str::of('{.foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - Label::of(Str::of('{.foo*}')), + Label::of(Str::of('{.foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - Label::of(Str::of('{.foo:42}')), + Label::of(Str::of('{.foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } public function testStringCast() { - $this->assertSame('{.foo}', Label::of(Str::of('{.foo}'))->toString()); - $this->assertSame('{.foo*}', Label::of(Str::of('{.foo*}'))->toString()); - $this->assertSame('{.foo:42}', Label::of(Str::of('{.foo:42}'))->toString()); + $this->assertSame( + '{.foo}', + Label::of(Str::of('{.foo}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{.foo*}', + Label::of(Str::of('{.foo*}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{.foo:42}', + Label::of(Str::of('{.foo:42}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); } - public function testThrowWhenNegativeLimit() + public function testReturnNothingWhenNegativeLimit() { $this ->forAll(Set\Integers::below(1)) ->then(function(int $int): void { - $this->expectException(DomainException::class); - - Label::of(Str::of("{.foo:$int}")); + $this->assertNull(Label::of(Str::of("{.foo:$int}"))->match( + static fn($expression) => $expression, + static fn() => null, + )); }); } @@ -68,23 +95,38 @@ public function testExpand() $this->assertSame( '.val', - Label::of(Str::of('{.var:3}'))->expand($variables), + Label::of(Str::of('{.var:3}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '.red,green,blue', - Label::of(Str::of('{.list}'))->expand($variables), + Label::of(Str::of('{.list}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '.red.green.blue', - Label::of(Str::of('{.list*}'))->expand($variables), + Label::of(Str::of('{.list*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '.semi,%3B,dot,.,comma,%2C', - Label::of(Str::of('{.keys}'))->expand($variables), + Label::of(Str::of('{.keys}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '.semi=%3B.dot=..comma=%2C', - Label::of(Str::of('{.keys*}'))->expand($variables), + Label::of(Str::of('{.keys*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -92,45 +134,63 @@ public function testOf() { $this->assertInstanceOf( Label::class, - $expression = Label::of(Str::of('{.foo}')), + $expression = Label::of(Str::of('{.foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{.foo}', $expression->toString()); $this->assertInstanceOf( Label::class, - $expression = Label::of(Str::of('{.foo*}')), + $expression = Label::of(Str::of('{.foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{.foo*}', $expression->toString()); $this->assertInstanceOf( Label::class, - $expression = Label::of(Str::of('{.foo:42}')), + $expression = Label::of(Str::of('{.foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{.foo:42}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{foo}'); - - Label::of(Str::of('{foo}')); + $this->assertNull(Label::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testThrowExplodeRegex() { $this->expectException(LogicException::class); - Label::of(Str::of('{.foo*}'))->regex(); + Label::of(Str::of('{.foo*}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ); } public function testRegex() { $this->assertSame( '\.(?[a-zA-Z0-9\%\-\.\_\~]*)', - Label::of(Str::of('{.foo}'))->regex(), + Label::of(Str::of('{.foo}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '\.(?[a-zA-Z0-9\%\-\.\_\~]{2})', - Label::of(Str::of('{.foo:2}'))->regex(), + Label::of(Str::of('{.foo:2}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level4/ParametersTest.php b/tests/Expression/Level4/ParametersTest.php index afccd84..a58d9ec 100644 --- a/tests/Expression/Level4/ParametersTest.php +++ b/tests/Expression/Level4/ParametersTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level4\Parameters, Expression, - Exception\DomainException, Exception\LogicException, }; use Innmind\Immutable\{ @@ -27,33 +26,61 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Parameters::of(Str::of('{;foo}')), + Parameters::of(Str::of('{;foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - Parameters::of(Str::of('{;foo*}')), + Parameters::of(Str::of('{;foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - Parameters::of(Str::of('{;foo:42}')), + Parameters::of(Str::of('{;foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } public function testStringCast() { - $this->assertSame('{;foo}', Parameters::of(Str::of('{;foo}'))->toString()); - $this->assertSame('{;foo*}', Parameters::of(Str::of('{;foo*}'))->toString()); - $this->assertSame('{;foo:42}', Parameters::of(Str::of('{;foo:42}'))->toString()); + $this->assertSame( + '{;foo}', + Parameters::of(Str::of('{;foo}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{;foo*}', + Parameters::of(Str::of('{;foo*}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{;foo:42}', + Parameters::of(Str::of('{;foo:42}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); } - public function testThrowWhenNegativeLimit() + public function testReturnNothingWhenNegativeLimit() { $this ->forAll(Set\Integers::below(1)) ->then(function(int $int): void { - $this->expectException(DomainException::class); - - Parameters::of(Str::of("{;foo:$int}")); + $this->assertNull(Parameters::of(Str::of("{;foo:$int}"))->match( + static fn($expression) => $expression, + static fn() => null, + )); }); } @@ -68,23 +95,38 @@ public function testExpand() $this->assertSame( ';hello=Hello', - Parameters::of(Str::of('{;hello:5}'))->expand($variables), + Parameters::of(Str::of('{;hello:5}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( ';list=red,green,blue', - Parameters::of(Str::of('{;list}'))->expand($variables), + Parameters::of(Str::of('{;list}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( ';list=red;list=green;list=blue', - Parameters::of(Str::of('{;list*}'))->expand($variables), + Parameters::of(Str::of('{;list*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( ';keys=semi,%3B,dot,.,comma,%2C', - Parameters::of(Str::of('{;keys}'))->expand($variables), + Parameters::of(Str::of('{;keys}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( ';semi=%3B;dot=.;comma=%2C', - Parameters::of(Str::of('{;keys*}'))->expand($variables), + Parameters::of(Str::of('{;keys*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -92,45 +134,63 @@ public function testOf() { $this->assertInstanceOf( Parameters::class, - $expression = Parameters::of(Str::of('{;foo}')), + $expression = Parameters::of(Str::of('{;foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{;foo}', $expression->toString()); $this->assertInstanceOf( Parameters::class, - $expression = Parameters::of(Str::of('{;foo*}')), + $expression = Parameters::of(Str::of('{;foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{;foo*}', $expression->toString()); $this->assertInstanceOf( Parameters::class, - $expression = Parameters::of(Str::of('{;foo:42}')), + $expression = Parameters::of(Str::of('{;foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{;foo:42}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{foo}'); - - Parameters::of(Str::of('{foo}')); + $this->assertNull(Parameters::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testThrowExplodeRegex() { $this->expectException(LogicException::class); - Parameters::of(Str::of('{;foo*}'))->regex(); + Parameters::of(Str::of('{;foo*}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ); } public function testRegex() { $this->assertSame( '\;foo=(?[a-zA-Z0-9\%\-\.\_\~]*)', - Parameters::of(Str::of('{;foo}'))->regex(), + Parameters::of(Str::of('{;foo}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '\;foo=(?[a-zA-Z0-9\%\-\.\_\~]{2})', - Parameters::of(Str::of('{;foo:2}'))->regex(), + Parameters::of(Str::of('{;foo:2}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level4/PathTest.php b/tests/Expression/Level4/PathTest.php index 1c64403..0cd2dac 100644 --- a/tests/Expression/Level4/PathTest.php +++ b/tests/Expression/Level4/PathTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level4\Path, Expression, - Exception\DomainException, Exception\LogicException, }; use Innmind\Immutable\{ @@ -27,33 +26,61 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Path::of(Str::of('{/foo}')), + Path::of(Str::of('{/foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - Path::of(Str::of('{/foo*}')), + Path::of(Str::of('{/foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - Path::of(Str::of('{/foo:42}')), + Path::of(Str::of('{/foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } public function testStringCast() { - $this->assertSame('{/foo}', Path::of(Str::of('{/foo}'))->toString()); - $this->assertSame('{/foo*}', Path::of(Str::of('{/foo*}'))->toString()); - $this->assertSame('{/foo:42}', Path::of(Str::of('{/foo:42}'))->toString()); + $this->assertSame( + '{/foo}', + Path::of(Str::of('{/foo}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{/foo*}', + Path::of(Str::of('{/foo*}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{/foo:42}', + Path::of(Str::of('{/foo:42}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); } - public function testThrowWhenNegativeLimit() + public function testReturnNothingWhenNegativeLimit() { $this ->forAll(Set\Integers::below(1)) ->then(function(int $int): void { - $this->expectException(DomainException::class); - - Path::of(Str::of("{/foo:$int}")); + $this->assertNull(Path::of(Str::of("{/foo:$int}"))->match( + static fn($expression) => $expression, + static fn() => null, + )); }); } @@ -68,19 +95,31 @@ public function testExpand() $this->assertSame( '/red,green,blue', - Path::of(Str::of('{/list}'))->expand($variables), + Path::of(Str::of('{/list}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '/red/green/blue', - Path::of(Str::of('{/list*}'))->expand($variables), + Path::of(Str::of('{/list*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '/semi,%3B,dot,.,comma,%2C', - Path::of(Str::of('{/keys}'))->expand($variables), + Path::of(Str::of('{/keys}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '/semi=%3B/dot=./comma=%2C', - Path::of(Str::of('{/keys*}'))->expand($variables), + Path::of(Str::of('{/keys*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -88,45 +127,63 @@ public function testOf() { $this->assertInstanceOf( Path::class, - $expression = Path::of(Str::of('{/foo}')), + $expression = Path::of(Str::of('{/foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{/foo}', $expression->toString()); $this->assertInstanceOf( Path::class, - $expression = Path::of(Str::of('{/foo*}')), + $expression = Path::of(Str::of('{/foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{/foo*}', $expression->toString()); $this->assertInstanceOf( Path::class, - $expression = Path::of(Str::of('{/foo:42}')), + $expression = Path::of(Str::of('{/foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{/foo:42}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{foo}'); - - Path::of(Str::of('{foo}')); + $this->assertNull(Path::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testThrowExplodeRegex() { $this->expectException(LogicException::class); - Path::of(Str::of('{/foo*}'))->regex(); + Path::of(Str::of('{/foo*}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ); } public function testRegex() { $this->assertSame( '\/(?[a-zA-Z0-9\%\-\.\_\~]*)', - Path::of(Str::of('{/foo}'))->regex(), + Path::of(Str::of('{/foo}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '\/(?[a-zA-Z0-9\%\-\.\_\~]{2})', - Path::of(Str::of('{/foo:2}'))->regex(), + Path::of(Str::of('{/foo:2}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level4/QueryContinuationTest.php b/tests/Expression/Level4/QueryContinuationTest.php index d711f25..b2f807b 100644 --- a/tests/Expression/Level4/QueryContinuationTest.php +++ b/tests/Expression/Level4/QueryContinuationTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level4\QueryContinuation, Expression, - Exception\DomainException, Exception\LogicException, }; use Innmind\Immutable\{ @@ -27,33 +26,61 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - QueryContinuation::of(Str::of('{&foo}')), + QueryContinuation::of(Str::of('{&foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - QueryContinuation::of(Str::of('{&foo*}')), + QueryContinuation::of(Str::of('{&foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - QueryContinuation::of(Str::of('{&foo:42}')), + QueryContinuation::of(Str::of('{&foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } public function testStringCast() { - $this->assertSame('{&foo}', QueryContinuation::of(Str::of('{&foo}'))->toString()); - $this->assertSame('{&foo*}', QueryContinuation::of(Str::of('{&foo*}'))->toString()); - $this->assertSame('{&foo:42}', QueryContinuation::of(Str::of('{&foo:42}'))->toString()); + $this->assertSame( + '{&foo}', + QueryContinuation::of(Str::of('{&foo}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{&foo*}', + QueryContinuation::of(Str::of('{&foo*}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{&foo:42}', + QueryContinuation::of(Str::of('{&foo:42}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); } - public function testThrowWhenNegativeLimit() + public function testReturnNothingWhenNegativeLimit() { $this ->forAll(Set\Integers::below(1)) ->then(function(int $int): void { - $this->expectException(DomainException::class); - - QueryContinuation::of(Str::of("{&foo:$int}")); + $this->assertNull(QueryContinuation::of(Str::of("{&foo:$int}"))->match( + static fn($expression) => $expression, + static fn() => null, + )); }); } @@ -68,23 +95,38 @@ public function testExpand() $this->assertSame( '&var=val', - QueryContinuation::of(Str::of('{&var:3}'))->expand($variables), + QueryContinuation::of(Str::of('{&var:3}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '&list=red,green,blue', - QueryContinuation::of(Str::of('{&list}'))->expand($variables), + QueryContinuation::of(Str::of('{&list}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '&list=red&list=green&list=blue', - QueryContinuation::of(Str::of('{&list*}'))->expand($variables), + QueryContinuation::of(Str::of('{&list*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '&keys=semi,%3B,dot,.,comma,%2C', - QueryContinuation::of(Str::of('{&keys}'))->expand($variables), + QueryContinuation::of(Str::of('{&keys}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '&semi=%3B&dot=.&comma=%2C', - QueryContinuation::of(Str::of('{&keys*}'))->expand($variables), + QueryContinuation::of(Str::of('{&keys*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -92,45 +134,63 @@ public function testOf() { $this->assertInstanceOf( QueryContinuation::class, - $expression = QueryContinuation::of(Str::of('{&foo}')), + $expression = QueryContinuation::of(Str::of('{&foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{&foo}', $expression->toString()); $this->assertInstanceOf( QueryContinuation::class, - $expression = QueryContinuation::of(Str::of('{&foo*}')), + $expression = QueryContinuation::of(Str::of('{&foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{&foo*}', $expression->toString()); $this->assertInstanceOf( QueryContinuation::class, - $expression = QueryContinuation::of(Str::of('{&foo:42}')), + $expression = QueryContinuation::of(Str::of('{&foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{&foo:42}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{foo}'); - - QueryContinuation::of(Str::of('{foo}')); + $this->assertNull(QueryContinuation::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testThrowExplodeRegex() { $this->expectException(LogicException::class); - QueryContinuation::of(Str::of('{&foo*}'))->regex(); + QueryContinuation::of(Str::of('{&foo*}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ); } public function testRegex() { $this->assertSame( '\&foo=(?[a-zA-Z0-9\%\-\.\_\~]*)', - QueryContinuation::of(Str::of('{&foo}'))->regex(), + QueryContinuation::of(Str::of('{&foo}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '\&foo=(?[a-zA-Z0-9\%\-\.\_\~]{2})', - QueryContinuation::of(Str::of('{&foo:2}'))->regex(), + QueryContinuation::of(Str::of('{&foo:2}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level4/QueryTest.php b/tests/Expression/Level4/QueryTest.php index efbb99d..0c4d636 100644 --- a/tests/Expression/Level4/QueryTest.php +++ b/tests/Expression/Level4/QueryTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level4\Query, Expression, - Exception\DomainException, Exception\LogicException, }; use Innmind\Immutable\{ @@ -27,33 +26,61 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Query::of(Str::of('{?foo}')), + Query::of(Str::of('{?foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - Query::of(Str::of('{?foo*}')), + Query::of(Str::of('{?foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - Query::of(Str::of('{?foo:42}')), + Query::of(Str::of('{?foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } public function testStringCast() { - $this->assertSame('{?foo}', Query::of(Str::of('{?foo}'))->toString()); - $this->assertSame('{?foo*}', Query::of(Str::of('{?foo*}'))->toString()); - $this->assertSame('{?foo:42}', Query::of(Str::of('{?foo:42}'))->toString()); + $this->assertSame( + '{?foo}', + Query::of(Str::of('{?foo}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{?foo*}', + Query::of(Str::of('{?foo*}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{?foo:42}', + Query::of(Str::of('{?foo:42}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); } - public function testThrowWhenNegativeLimit() + public function testReturnNothingWhenNegativeLimit() { $this ->forAll(Set\Integers::below(1)) ->then(function(int $int): void { - $this->expectException(DomainException::class); - - Query::of(Str::of("{?foo:$int}")); + $this->assertNull(Query::of(Str::of("{?foo:$int}"))->match( + static fn($expression) => $expression, + static fn() => null, + )); }); } @@ -68,23 +95,38 @@ public function testExpand() $this->assertSame( '?var=val', - Query::of(Str::of('{?var:3}'))->expand($variables), + Query::of(Str::of('{?var:3}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '?list=red,green,blue', - Query::of(Str::of('{?list}'))->expand($variables), + Query::of(Str::of('{?list}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '?list=red&list=green&list=blue', - Query::of(Str::of('{?list*}'))->expand($variables), + Query::of(Str::of('{?list*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '?keys=semi,%3B,dot,.,comma,%2C', - Query::of(Str::of('{?keys}'))->expand($variables), + Query::of(Str::of('{?keys}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '?semi=%3B&dot=.&comma=%2C', - Query::of(Str::of('{?keys*}'))->expand($variables), + Query::of(Str::of('{?keys*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -92,45 +134,63 @@ public function testOf() { $this->assertInstanceOf( Query::class, - $expression = Query::of(Str::of('{?foo}')), + $expression = Query::of(Str::of('{?foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{?foo}', $expression->toString()); $this->assertInstanceOf( Query::class, - $expression = Query::of(Str::of('{?foo*}')), + $expression = Query::of(Str::of('{?foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{?foo*}', $expression->toString()); $this->assertInstanceOf( Query::class, - $expression = Query::of(Str::of('{?foo:42}')), + $expression = Query::of(Str::of('{?foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{?foo:42}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{foo}'); - - Query::of(Str::of('{foo}')); + $this->assertNull(Query::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testThrowExplodeRegex() { $this->expectException(LogicException::class); - Query::of(Str::of('{?foo*}'))->regex(); + Query::of(Str::of('{?foo*}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ); } public function testRegex() { $this->assertSame( '\?foo=(?[a-zA-Z0-9\%\-\.\_\~]*)', - Query::of(Str::of('{?foo}'))->regex(), + Query::of(Str::of('{?foo}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '\?foo=(?[a-zA-Z0-9\%\-\.\_\~]{2})', - Query::of(Str::of('{?foo:2}'))->regex(), + Query::of(Str::of('{?foo:2}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level4/ReservedTest.php b/tests/Expression/Level4/ReservedTest.php index c3c9f47..ef735cc 100644 --- a/tests/Expression/Level4/ReservedTest.php +++ b/tests/Expression/Level4/ReservedTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level4\Reserved, Expression, - Exception\DomainException, Exception\LogicException, }; use Innmind\Immutable\{ @@ -27,33 +26,61 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Reserved::of(Str::of('{+foo}')), + Reserved::of(Str::of('{+foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - Reserved::of(Str::of('{+foo*}')), + Reserved::of(Str::of('{+foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - Reserved::of(Str::of('{+foo:42}')), + Reserved::of(Str::of('{+foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } public function testStringCast() { - $this->assertSame('{+foo}', Reserved::of(Str::of('{+foo}'))->toString()); - $this->assertSame('{+foo*}', Reserved::of(Str::of('{+foo*}'))->toString()); - $this->assertSame('{+foo:42}', Reserved::of(Str::of('{+foo:42}'))->toString()); + $this->assertSame( + '{+foo}', + Reserved::of(Str::of('{+foo}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{+foo*}', + Reserved::of(Str::of('{+foo*}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{+foo:42}', + Reserved::of(Str::of('{+foo:42}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); } - public function testThrowWhenNegativeLimit() + public function testReturnNothingWhenNegativeLimit() { $this ->forAll(Set\Integers::below(1)) ->then(function(int $int): void { - $this->expectException(DomainException::class); - - Reserved::of(Str::of("{+foo:$int}")); + $this->assertNull(Reserved::of(Str::of("{+foo:$int}"))->match( + static fn($expression) => $expression, + static fn() => null, + )); }); } @@ -68,23 +95,38 @@ public function testExpand() $this->assertSame( '/foo/b', - Reserved::of(Str::of('{+path:6}'))->expand($variables), + Reserved::of(Str::of('{+path:6}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( 'red,green,blue', - Reserved::of(Str::of('{+list}'))->expand($variables), + Reserved::of(Str::of('{+list}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( 'red,green,blue', - Reserved::of(Str::of('{+list*}'))->expand($variables), + Reserved::of(Str::of('{+list*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( 'semi,;,dot,.,comma,,', - Reserved::of(Str::of('{+keys}'))->expand($variables), + Reserved::of(Str::of('{+keys}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( 'semi=;,dot=.,comma=,', - Reserved::of(Str::of('{+keys*}'))->expand($variables), + Reserved::of(Str::of('{+keys*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -92,45 +134,63 @@ public function testOf() { $this->assertInstanceOf( Reserved::class, - $expression = Reserved::of(Str::of('{+foo}')), + $expression = Reserved::of(Str::of('{+foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{+foo}', $expression->toString()); $this->assertInstanceOf( Reserved::class, - $expression = Reserved::of(Str::of('{+foo*}')), + $expression = Reserved::of(Str::of('{+foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{+foo*}', $expression->toString()); $this->assertInstanceOf( Reserved::class, - $expression = Reserved::of(Str::of('{+foo:42}')), + $expression = Reserved::of(Str::of('{+foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{+foo:42}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('{foo}'); - - Reserved::of(Str::of('{foo}')); + $this->assertNull(Reserved::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testThrowExplodeRegex() { $this->expectException(LogicException::class); - Reserved::of(Str::of('{+foo*}'))->regex(); + Reserved::of(Str::of('{+foo*}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ); } public function testRegex() { $this->assertSame( '(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]*)', - Reserved::of(Str::of('{+foo}'))->regex(), + Reserved::of(Str::of('{+foo}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '(?[a-zA-Z0-9\%:/\?#\[\]@!$&\'\(\)\*\+,;=\-\.\_\~]{2})', - Reserved::of(Str::of('{+foo:2}'))->regex(), + Reserved::of(Str::of('{+foo:2}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } diff --git a/tests/Expression/Level4Test.php b/tests/Expression/Level4Test.php index dd7bb2d..46e1a93 100644 --- a/tests/Expression/Level4Test.php +++ b/tests/Expression/Level4Test.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level4, Expression, - Exception\DomainException, Exception\LogicException, }; use Innmind\Immutable\{ @@ -27,33 +26,61 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - Level4::of(Str::of('{foo}')), + Level4::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - Level4::of(Str::of('{foo*}')), + Level4::of(Str::of('{foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertInstanceOf( Expression::class, - Level4::of(Str::of('{foo:42}')), + Level4::of(Str::of('{foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); } public function testStringCast() { - $this->assertSame('{foo}', Level4::of(Str::of('{foo}'))->toString()); - $this->assertSame('{foo*}', Level4::of(Str::of('{foo*}'))->toString()); - $this->assertSame('{foo:42}', Level4::of(Str::of('{foo:42}'))->toString()); + $this->assertSame( + '{foo}', + Level4::of(Str::of('{foo}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{foo*}', + Level4::of(Str::of('{foo*}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); + $this->assertSame( + '{foo:42}', + Level4::of(Str::of('{foo:42}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), + ); } - public function testThrowWhenNegativeLimit() + public function testReturnNothingWhenNegativeLimit() { $this ->forAll(Set\Integers::below(1)) ->then(function(int $int): void { - $this->expectException(DomainException::class); - - Level4::of(Str::of("{foo:$int}")); + $this->assertNull(Level4::of(Str::of("{foo:$int}"))->match( + static fn($expression) => $expression, + static fn() => null, + )); }); } @@ -68,31 +95,52 @@ public function testExpand() $this->assertSame( 'val', - Level4::of(Str::of('{var:3}'))->expand($variables), + Level4::of(Str::of('{var:3}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( 'value', - Level4::of(Str::of('{var:30}'))->expand($variables), + Level4::of(Str::of('{var:30}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '%2Ffoo', - Level4::of(Str::of('{path:4}'))->expand($variables), + Level4::of(Str::of('{path:4}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( 'red,green,blue', - Level4::of(Str::of('{list}'))->expand($variables), + Level4::of(Str::of('{list}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( 'red,green,blue', - Level4::of(Str::of('{list*}'))->expand($variables), + Level4::of(Str::of('{list*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( 'semi,%3B,dot,.,comma,%2C', - Level4::of(Str::of('{keys}'))->expand($variables), + Level4::of(Str::of('{keys}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( 'semi=%3B,dot=.,comma=%2C', - Level4::of(Str::of('{keys*}'))->expand($variables), + Level4::of(Str::of('{keys*}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } @@ -100,45 +148,63 @@ public function testOf() { $this->assertInstanceOf( Level4::class, - $expression = Level4::of(Str::of('{foo}')), + $expression = Level4::of(Str::of('{foo}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{foo}', $expression->toString()); $this->assertInstanceOf( Level4::class, - $expression = Level4::of(Str::of('{foo*}')), + $expression = Level4::of(Str::of('{foo*}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{foo*}', $expression->toString()); $this->assertInstanceOf( Level4::class, - $expression = Level4::of(Str::of('{foo:42}')), + $expression = Level4::of(Str::of('{foo:42}'))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame('{foo:42}', $expression->toString()); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('foo'); - - Level4::of(Str::of('foo')); + $this->assertNull(Level4::of(Str::of('foo'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function testThrowExplodeRegex() { $this->expectException(LogicException::class); - Level4::of(Str::of('{foo*}'))->regex(); + Level4::of(Str::of('{foo*}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ); } public function testRegex() { $this->assertSame( '(?[a-zA-Z0-9\%\-\.\_\~]*)', - Level4::of(Str::of('{foo}'))->regex(), + Level4::of(Str::of('{foo}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); $this->assertSame( '(?[a-zA-Z0-9\%\-\.\_\~]{2})', - Level4::of(Str::of('{foo:2}'))->regex(), + Level4::of(Str::of('{foo:2}'))->match( + static fn($expression) => $expression->regex(), + static fn() => null, + ), ); } } From 4c4986395402dfc7bbd8ccb8ed0c56f4d7a53b87 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 14:52:03 +0200 Subject: [PATCH 16/39] parse the template before constructing the object --- src/Template.php | 74 +++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/src/Template.php b/src/Template.php index 2da3875..80ce389 100644 --- a/src/Template.php +++ b/src/Template.php @@ -24,16 +24,13 @@ final class Template /** @var Sequence */ private Sequence $expressions; - private function __construct(string $template) + /** + * @param Sequence $expressions + */ + private function __construct(Str $template, Sequence $expressions) { - $this->template = Str::of($template); - $this->expressions = $this - ->extractExpressions( - Sequence::of(), - $this->template, - ) - ->map(Str::of(...)) - ->map(Expressions::of(...)); + $this->template = $template; + $this->expressions = $expressions; } /** @@ -41,7 +38,9 @@ private function __construct(string $template) */ public static function of(string $template): self { - return new self($template); + $template = Str::of($template); + + return new self($template, self::parse($template)); } /** @@ -94,31 +93,6 @@ public function toString(): string return $this->template->toString(); } - /** - * Recursively find the expressions as Str::capture doesnt capture all of - * them at the same time - * @param Sequence $expressions - * - * @return Sequence - */ - private function extractExpressions( - Sequence $expressions, - Str $template, - ): Sequence { - $captured = $template->capture('~(\{[\+#\./;\?&]?[a-zA-Z0-9_]+(\*|:\d+)?(,[a-zA-Z0-9_]+(\*|:\d+)?)*\})~'); - - return $captured - ->values() - ->first() - ->match( - fn($value) => $this->extractExpressions( - $expressions->add($value->toString()), - $template->replace($value->toString(), ''), - ), - static fn() => $expressions, - ); - } - private function regex(): string { try { @@ -163,4 +137,34 @@ static function(Str $template, Expression $expression) use (&$j): Str { return $template->prepend('~^')->append('$~')->toString(); } + + /** + * @psalm-pure + * + * Recursively find the expressions as Str::capture doesnt capture all of + * them at the same time + * + * @return Sequence + */ + private static function parse(Str $template): Sequence + { + /** @var Sequence */ + $expressions = Sequence::of(); + + do { + $captured = $template->capture('~(\{[\+#\./;\?&]?[a-zA-Z0-9_]+(\*|:\d+)?(,[a-zA-Z0-9_]+(\*|:\d+)?)*\})~'); + + [$expressions, $template] = $captured + ->get(0) + ->match( + static fn($value) => [ + ($expressions)($value), + $template->replace($value->toString(), ''), + ], + static fn() => [$expressions, $template], + ); + } while (!$captured->empty()); + + return $expressions->map(Expressions::of(...)); + } } From 2ae765403490d5a3a04afbfe1dba69adb8177a24 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 15:06:11 +0200 Subject: [PATCH 17/39] force the use of literal string in Template::of and add Template::maybe --- src/Expression/Level4/Composite.php | 2 +- src/Expressions.php | 27 ++++++++++----------- src/Template.php | 37 +++++++++++++++++++++++++---- tests/ExpressionsTest.php | 21 +++++++++------- 4 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/Expression/Level4/Composite.php b/src/Expression/Level4/Composite.php index 13e75e3..0fd4b3c 100644 --- a/src/Expression/Level4/Composite.php +++ b/src/Expression/Level4/Composite.php @@ -67,7 +67,7 @@ public static function of(Str $string): Maybe static fn($pieces) => $pieces ->first() ->map(static fn($first) => $first->prepend('{')->append('}')) - ->map(Expressions::of(...)) + ->flatMap(Expressions::of(...)) ->map( static fn($first) => $pieces->drop(1)->reduce( $first, diff --git a/src/Expressions.php b/src/Expressions.php index ed45e5c..452baac 100644 --- a/src/Expressions.php +++ b/src/Expressions.php @@ -3,7 +3,6 @@ namespace Innmind\UrlTemplate; -use Innmind\UrlTemplate\Exception\DomainException; use Innmind\Immutable\{ Sequence, Str, @@ -17,21 +16,21 @@ final class Expressions { /** * @psalm-pure + * + * @return Maybe */ - public static function of(Str $string): Expression + public static function of(Str $string): Maybe { - /** @psalm-suppress MixedArgumentTypeCoercion */ - return self::expressions() - ->reduce( - Maybe::nothing(), - static fn(Maybe $expression, $attempt) => $expression->otherwise( - static fn() => $attempt($string), - ), - ) - ->match( - static fn(Expression $expression): Expression => $expression, - static fn() => throw new DomainException($string->toString()), - ); + /** + * @psalm-suppress MixedReturnTypeCoercion + * @var Maybe + */ + return self::expressions()->reduce( + Maybe::nothing(), + static fn(Maybe $expression, $attempt) => $expression->otherwise( + static fn() => $attempt($string), + ), + ); } /** diff --git a/src/Template.php b/src/Template.php index 80ce389..e4964f1 100644 --- a/src/Template.php +++ b/src/Template.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\Exception\{ UrlDoesntMatchTemplate, ExtractionNotSupported, + DomainException, LogicException, }; use Innmind\Url\Url; @@ -13,6 +14,7 @@ Map, Sequence, Str, + Maybe, }; /** @@ -35,12 +37,31 @@ private function __construct(Str $template, Sequence $expressions) /** * @psalm-pure + * + * @param literal-string $template + * + * @throws DomainException */ public static function of(string $template): self + { + return self::maybe($template)->match( + static fn($self) => $self, + static fn() => throw new DomainException($template), + ); + } + + /** + * @psalm-pure + * + * @return Maybe + */ + public static function maybe(string $template): Maybe { $template = Str::of($template); - return new self($template, self::parse($template)); + return self::parse($template)->map( + static fn($expressions) => new self($template, $expressions), + ); } /** @@ -144,9 +165,9 @@ static function(Str $template, Expression $expression) use (&$j): Str { * Recursively find the expressions as Str::capture doesnt capture all of * them at the same time * - * @return Sequence + * @return Maybe> */ - private static function parse(Str $template): Sequence + private static function parse(Str $template): Maybe { /** @var Sequence */ $expressions = Sequence::of(); @@ -165,6 +186,14 @@ private static function parse(Str $template): Sequence ); } while (!$captured->empty()); - return $expressions->map(Expressions::of(...)); + /** @var Maybe> */ + return $expressions + ->map(Expressions::of(...)) + ->match( + static fn($first, $rest) => Maybe::all($first, ...$rest->toList())->map( + Sequence::of(...), + ), + static fn() => Maybe::just(Sequence::of()), + ); } } diff --git a/tests/ExpressionsTest.php b/tests/ExpressionsTest.php index 2e1cc63..0ffb298 100644 --- a/tests/ExpressionsTest.php +++ b/tests/ExpressionsTest.php @@ -7,7 +7,6 @@ Expressions, Expression\Level4, Expression\Level3, - Exception\DomainException, }; use Innmind\Immutable\Str; use PHPUnit\Framework\TestCase; @@ -21,20 +20,26 @@ public function testOf($string, $expected) { $this->assertInstanceOf( $expected, - Expressions::of(Str::of($string)), + Expressions::of(Str::of($string))->match( + static fn($expression) => $expression, + static fn() => null, + ), ); $this->assertSame( $string, - Expressions::of(Str::of($string))->toString(), + Expressions::of(Str::of($string))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), ); } - public function testThrowWhenInvalidPattern() + public function testReturnNothingWhenInvalidPattern() { - $this->expectException(DomainException::class); - $this->expectExceptionMessage('foo'); - - Expressions::of(Str::of('foo')); + $this->assertNull(Expressions::of(Str::of('foo'))->match( + static fn($expression) => $expression, + static fn() => null, + )); } public function cases(): array From b650e720b0d338010453a34cd2fc8c6b55324bb5 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 15:55:38 +0200 Subject: [PATCH 18/39] deduplicate parsing names --- src/Expression/Level1.php | 6 +- src/Expression/Level2/Fragment.php | 6 +- src/Expression/Level2/Reserved.php | 6 +- src/Expression/Level3.php | 10 +- src/Expression/Level3/Fragment.php | 10 +- src/Expression/Level3/Label.php | 10 +- src/Expression/Level3/Parameters.php | 10 +- src/Expression/Level3/Path.php | 10 +- src/Expression/Level3/Query.php | 10 +- src/Expression/Level3/QueryContinuation.php | 10 +- src/Expression/Level3/Reserved.php | 10 +- src/Expression/Level4/Parse.php | 57 ++------- src/Expression/Name.php | 128 +++++++++++++++++++- tests/Expression/Level3Test.php | 2 +- 14 files changed, 151 insertions(+), 134 deletions(-) diff --git a/src/Expression/Level1.php b/src/Expression/Level1.php index 8fd6917..6cf0ed7 100644 --- a/src/Expression/Level1.php +++ b/src/Expression/Level1.php @@ -34,11 +34,7 @@ private function __construct(Name $name) public static function of(Str $string): Maybe { /** @var Maybe */ - return Maybe::just($string) - ->filter(static fn($string) => $string->matches('~^\{[a-zA-Z0-9_]+\}$~')) - ->map(static fn($string) => $string->trim('{}')->toString()) - ->map(Name::of(...)) - ->map(static fn($name) => new self($name)); + return Name::one($string)->map(static fn($name) => new self($name)); } /** diff --git a/src/Expression/Level2/Fragment.php b/src/Expression/Level2/Fragment.php index 780e3c2..f7f80dc 100644 --- a/src/Expression/Level2/Fragment.php +++ b/src/Expression/Level2/Fragment.php @@ -35,11 +35,7 @@ private function __construct(Name $name) public static function of(Str $string): Maybe { /** @var Maybe */ - return Maybe::just($string) - ->filter(static fn($string) => $string->matches('~^\{#[a-zA-Z0-9_]+\}$~')) - ->map(static fn($string) => $string->trim('{#}')->toString()) - ->map(Name::of(...)) - ->map(static fn($name) => new self($name)); + return Name::one($string, '#')->map(static fn($name) => new self($name)); } public function expand(Map $variables): string diff --git a/src/Expression/Level2/Reserved.php b/src/Expression/Level2/Reserved.php index 10fa0c5..5b6380d 100644 --- a/src/Expression/Level2/Reserved.php +++ b/src/Expression/Level2/Reserved.php @@ -35,11 +35,7 @@ private function __construct(Name $name) public static function of(Str $string): Maybe { /** @var Maybe */ - return Maybe::just($string) - ->filter(static fn($string) => $string->matches('~^\{\+[a-zA-Z0-9_]+\}$~')) - ->map(static fn($string) => $string->trim('{+}')->toString()) - ->map(Name::of(...)) - ->map(static fn($name) => new self($name)); + return Name::one($string, '+')->map(static fn($name) => new self($name)); } /** diff --git a/src/Expression/Level3.php b/src/Expression/Level3.php index c92e628..768a102 100644 --- a/src/Expression/Level3.php +++ b/src/Expression/Level3.php @@ -36,15 +36,7 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Maybe::just($string) - ->filter(static fn($string) => $string->matches('~^\{[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)+\}$~')) - ->map(static fn($string) => $string->trim('{}')->split(',')) - ->map( - static fn($names) => $names - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ) - ->map(static fn($names) => new self($names)); + return Name::many($string)->map(static fn($names) => new self($names)); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Fragment.php b/src/Expression/Level3/Fragment.php index d39401a..47dc608 100644 --- a/src/Expression/Level3/Fragment.php +++ b/src/Expression/Level3/Fragment.php @@ -41,15 +41,7 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Maybe::just($string) - ->filter(static fn($string) => $string->matches('~^\{#[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) - ->map(static fn($string) => $string->trim('{#}')->split(',')) - ->map( - static fn($names) => $names - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ) - ->map(static fn($names) => new self($names)); + return Name::many($string, '#')->map(static fn($names) => new self($names)); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Label.php b/src/Expression/Level3/Label.php index 6dc5ba2..65f5505 100644 --- a/src/Expression/Level3/Label.php +++ b/src/Expression/Level3/Label.php @@ -41,15 +41,7 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Maybe::just($string) - ->filter(static fn($string) => $string->matches('~^\{\.[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) - ->map(static fn($string) => $string->trim('{.}')->split(',')) - ->map( - static fn($names) => $names - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ) - ->map(static fn($names) => new self($names)); + return Name::many($string, '.')->map(static fn($names) => new self($names)); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Parameters.php b/src/Expression/Level3/Parameters.php index 4e80d98..af642c6 100644 --- a/src/Expression/Level3/Parameters.php +++ b/src/Expression/Level3/Parameters.php @@ -35,15 +35,7 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Maybe::just($string) - ->filter(static fn($string) => $string->matches('~^\{;[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) - ->map(static fn($string) => $string->trim('{;}')->split(',')) - ->map( - static fn($names) => $names - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ) - ->map(static fn($names) => new self($names)); + return Name::many($string, ';')->map(static fn($names) => new self($names)); } /** diff --git a/src/Expression/Level3/Path.php b/src/Expression/Level3/Path.php index 230a3da..62fd155 100644 --- a/src/Expression/Level3/Path.php +++ b/src/Expression/Level3/Path.php @@ -41,15 +41,7 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Maybe::just($string) - ->filter(static fn($string) => $string->matches('~^\{/[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) - ->map(static fn($string) => $string->trim('{/}')->split(',')) - ->map( - static fn($names) => $names - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ) - ->map(static fn($names) => new self($names)); + return Name::many($string, '/')->map(static fn($names) => new self($names)); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Query.php b/src/Expression/Level3/Query.php index c2b16df..06d6605 100644 --- a/src/Expression/Level3/Query.php +++ b/src/Expression/Level3/Query.php @@ -35,15 +35,7 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Maybe::just($string) - ->filter(static fn($string) => $string->matches('~^\{\?[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) - ->map(static fn($string) => $string->trim('{?}')->split(',')) - ->map( - static fn($names) => $names - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ) - ->map(static fn($names) => new self($names)); + return Name::many($string, '?')->map(static fn($names) => new self($names)); } /** diff --git a/src/Expression/Level3/QueryContinuation.php b/src/Expression/Level3/QueryContinuation.php index 55db4bb..e9b2d6d 100644 --- a/src/Expression/Level3/QueryContinuation.php +++ b/src/Expression/Level3/QueryContinuation.php @@ -35,15 +35,7 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Maybe::just($string) - ->filter(static fn($string) => $string->matches('~^\{\&[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) - ->map(static fn($string) => $string->trim('{&}')->split(',')) - ->map( - static fn($names) => $names - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ) - ->map(static fn($names) => new self($names)); + return Name::many($string, '&')->map(static fn($names) => new self($names)); } public static function named(Name $name): self diff --git a/src/Expression/Level3/Reserved.php b/src/Expression/Level3/Reserved.php index fad6177..8fa23bd 100644 --- a/src/Expression/Level3/Reserved.php +++ b/src/Expression/Level3/Reserved.php @@ -41,15 +41,7 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Maybe::just($string) - ->filter(static fn($string) => $string->matches('~^\{\+[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}$~')) - ->map(static fn($string) => $string->trim('{+}')->split(',')) - ->map( - static fn($names) => $names - ->map(static fn($name) => $name->toString()) - ->map(Name::of(...)), - ) - ->map(static fn($names) => new self($names)); + return Name::many($string, '+')->map(static fn($names) => new self($names)); } public function expand(Map $variables): string diff --git a/src/Expression/Level4/Parse.php b/src/Expression/Level4/Parse.php index a2e8696..8141496 100644 --- a/src/Expression/Level4/Parse.php +++ b/src/Expression/Level4/Parse.php @@ -20,7 +20,7 @@ final class Parse * @param pure-callable(Name): Expression $standard * @param pure-callable(Name): Expression $explode * @param pure-callable(Name, positive-int): Expression $limit - * @param non-empty-string|null $lead + * @param ?non-empty-string $lead * * @return Maybe */ @@ -31,76 +31,43 @@ public static function of( callable $limit, string $lead = null, ): Maybe { - $drop = match ($lead) { - null => 1, - default => 2, - }; - $lead = match ($lead) { - null => '', - default => "\\$lead", - }; - - return Maybe::just($string) - ->filter(static fn($string) => $string->matches("~^\{{$lead}[a-zA-Z0-9_]+\}\$~")) - ->map(static fn($string) => $string->drop($drop)->dropEnd(1)->toString()) - ->map(Name::of(...)) + return Name::one($string, $lead) ->map($standard) - ->otherwise(static fn() => self::explode($string, $explode, $lead, $drop)) - ->otherwise(static fn() => self::limit($string, $limit, $lead, $drop)); + ->otherwise(static fn() => self::explode($string, $explode, $lead)) + ->otherwise(static fn() => self::limit($string, $limit, $lead)); } /** * @psalm-pure * * @param pure-callable(Name): Expression $explode - * @param positive-int $drop + * @param ?non-empty-string $lead * * @return Maybe */ private static function explode( Str $string, callable $explode, - string $lead, - int $drop, + string $lead = null, ): Maybe { - return Maybe::just($string) - ->filter(static fn($string) => $string->matches("~^\{{$lead}[a-zA-Z0-9_]+\*\}\$~")) - ->map(static fn($string) => $string->drop($drop)->dropEnd(2)->toString()) - ->map(Name::of(...)) - ->map($explode); + return Name::explode($string, $lead)->map($explode); } /** * @psalm-pure * * @param pure-callable(Name, positive-int): Expression $limit - * @param positive-int $drop + * @param ?non-empty-string $lead * * @return Maybe */ private static function limit( Str $string, callable $limit, - string $lead, - int $drop, + string $lead = null, ): Maybe { - /** @psalm-suppress ArgumentTypeCoercion For the positive-int */ - return Maybe::just($string) - ->filter(static fn($string) => $string->matches("~^\{{$lead}[a-zA-Z0-9_]+:\d+\}\$~")) - ->map(static fn($string) => $string->drop($drop)->dropEnd(1)->split(':')) - ->map(static fn($pieces) => $pieces->map(static fn($piece) => $piece->toString())) - ->flatMap( - static fn($pieces) => $pieces - ->first() - ->map(Name::of(...)) - ->flatMap( - static fn($name) => $pieces - ->last() - ->filter(\is_numeric(...)) - ->map(static fn($limit) => (int) $limit) - ->filter(static fn(int $limit) => $limit > 0) - ->map(static fn($int) => $limit($name, $int)), - ), - ); + return Name::limit($string, $lead)->map( + static fn($tuple) => $limit($tuple[0], $tuple[1]), + ); } } diff --git a/src/Expression/Name.php b/src/Expression/Name.php index ee49b0c..251cf12 100644 --- a/src/Expression/Name.php +++ b/src/Expression/Name.php @@ -4,7 +4,11 @@ namespace Innmind\UrlTemplate\Expression; use Innmind\UrlTemplate\Exception\DomainException; -use Innmind\Immutable\Str; +use Innmind\Immutable\{ + Str, + Maybe, + Sequence, +}; /** * @psalm-immutable @@ -30,8 +34,130 @@ public static function of(string $value): self return new self($value); } + /** + * @psalm-pure + * + * @param ?non-empty-string $lead + * + * @return Maybe + */ + public static function one( + Str $value, + string $lead = null, + ): Maybe { + return self::find($value, $lead) + ->map(static fn($value) => $value->toString()) + ->map(static fn($value) => new self($value)); + } + + /** + * @psalm-pure + * + * @param ?non-empty-string $lead + * + * @return Maybe + */ + public static function explode( + Str $value, + string $lead = null, + ): Maybe { + return self::find($value, $lead, '\\*') + ->map(static fn($value) => $value->toString()) + ->map(static fn($value) => new self($value)); + } + + /** + * @psalm-pure + * + * @param ?non-empty-string $lead + * + * @return Maybe + */ + public static function limit( + Str $value, + string $lead = null, + ): Maybe { + return self::find($value, $lead, ':\d+') + ->map(static fn($value) => $value->split(':')) + ->map(static fn($pieces) => $pieces->map(static fn($piece) => $piece->toString())) + ->flatMap( + static fn($pieces) => $pieces + ->first() + ->map(static fn($value) => new self($value)) + ->flatMap( + static fn($name) => $pieces + ->last() + ->filter(\is_numeric(...)) + ->map(static fn($limit) => (int) $limit) + ->filter(static fn(int $limit) => $limit > 0) + ->map(static fn($int) => [$name, $int]), + ), + ); + } + + /** + * @psalm-pure + * + * @param ?non-empty-string $lead + * + * @return Maybe> + */ + public static function many( + Str $value, + string $lead = null, + ): Maybe { + $drop = match ($lead) { + null => 1, + default => 2, + }; + $lead = match ($lead) { + null => '', + default => "\\$lead", + }; + + return Maybe::just($value) + ->filter(static fn($value) => $value->matches("~^\{{$lead}[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}\$~")) + ->map(static fn($value) => $value->drop($drop)->dropEnd(1)->split(',')) + ->map( + static fn($values) => $values + ->map(static fn($value) => $value->toString()) + ->map(static fn($value) => new self($value)), + ); + } + public function toString(): string { return $this->value; } + + /** + * @psalm-pure + * + * @param ?non-empty-string $lead + * @param ?non-empty-string $extra + * + * @return Maybe + */ + private static function find( + Str $value, + string $lead = null, + string $extra = null, + ): Maybe { + $drop = match ($lead) { + null => 1, + default => 2, + }; + $dropEnd = match ($extra) { + '\\*' => 2, + default => 1, + }; + $lead = match ($lead) { + null => '', + default => "\\$lead", + }; + + return Maybe::just($value) + ->filter(static fn($value) => $value->matches("~^\{{$lead}[a-zA-Z0-9_]+{$extra}\}\$~")) + ->map(static fn($value) => $value->drop($drop)->dropEnd($dropEnd)); + } } diff --git a/tests/Expression/Level3Test.php b/tests/Expression/Level3Test.php index a1f8eff..5cd1194 100644 --- a/tests/Expression/Level3Test.php +++ b/tests/Expression/Level3Test.php @@ -77,7 +77,7 @@ public function testOf() public function testReturnNothingWhenInvalidPattern() { - $this->assertNull(Level3::of(Str::of('{foo}'))->match( + $this->assertNull(Level3::of(Str::of('{foo'))->match( static fn($expression) => $expression, static fn() => null, )); From 37bb4d5a96576b024492722e8ed679bf5531a99a Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 15:56:52 +0200 Subject: [PATCH 19/39] remove unused property --- src/Expression/Level4/Composite.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Expression/Level4/Composite.php b/src/Expression/Level4/Composite.php index 0fd4b3c..4a0d73b 100644 --- a/src/Expression/Level4/Composite.php +++ b/src/Expression/Level4/Composite.php @@ -21,7 +21,6 @@ final class Composite implements Expression { private string $separator; - private string $type; /** @var Sequence */ private Sequence $expressions; private bool $removeLead = false; @@ -32,7 +31,6 @@ public function __construct( Expression ...$expressions, ) { $this->separator = $separator; - $this->type = \get_class($level4); $this->expressions = Sequence::of($level4, ...$expressions); } From bf4b21c84ca86bb5019ecd8e56957a0385445f3a Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 17:11:14 +0200 Subject: [PATCH 20/39] use Expansion enum instead of literal strings --- src/Expression/Expansion.php | 78 +++++++++++++++++++++ src/Expression/Level1.php | 4 +- src/Expression/Level2/Fragment.php | 5 +- src/Expression/Level2/Reserved.php | 5 +- src/Expression/Level3.php | 4 +- src/Expression/Level3/Fragment.php | 5 +- src/Expression/Level3/Label.php | 5 +- src/Expression/Level3/Parameters.php | 5 +- src/Expression/Level3/Path.php | 5 +- src/Expression/Level3/Query.php | 5 +- src/Expression/Level3/QueryContinuation.php | 5 +- src/Expression/Level3/Reserved.php | 5 +- src/Expression/Level4.php | 1 + src/Expression/Level4/Fragment.php | 3 +- src/Expression/Level4/Label.php | 3 +- src/Expression/Level4/Parameters.php | 3 +- src/Expression/Level4/Parse.php | 20 +++--- src/Expression/Level4/Path.php | 3 +- src/Expression/Level4/Query.php | 3 +- src/Expression/Level4/QueryContinuation.php | 3 +- src/Expression/Level4/Reserved.php | 3 +- src/Expression/Name.php | 75 +++++--------------- 22 files changed, 161 insertions(+), 87 deletions(-) create mode 100644 src/Expression/Expansion.php diff --git a/src/Expression/Expansion.php b/src/Expression/Expansion.php new file mode 100644 index 0000000..ed75491 --- /dev/null +++ b/src/Expression/Expansion.php @@ -0,0 +1,78 @@ + 1, + default => 2, + }; + + return $value->drop($drop)->dropEnd(1); + } + + public function cleanExplode(Str $value): Str + { + return $this->clean($value)->dropEnd(1); + } + + public function matches(Str $value): bool + { + return $value->matches("~^\{{$this->regex()}[a-zA-Z0-9_]+\}\$~"); + } + + public function matchesExplode(Str $value): bool + { + return $value->matches("~^\{{$this->regex()}[a-zA-Z0-9_]+\*\}\$~"); + } + + public function matchesLimit(Str $value): bool + { + return $value->matches("~^\{{$this->regex()}[a-zA-Z0-9_]+:\d+\}\$~"); + } + + public function matchesMany(Str $value): bool + { + return $value->matches("~^\{{$this->regex()}[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}\$~"); + } + + private function regex(): string + { + return match ($this) { + self::simple => '', + default => '\\'.$this->toString(), + }; + } + + private function toString(): string + { + return match ($this) { + self::simple => '', + self::reserved => '+', + self::fragment => '#', + self::label => '.', + self::path => '/', + self::parameter => ';', + self::query => '?', + self::queryContinuation => '&', + }; + } +} diff --git a/src/Expression/Level1.php b/src/Expression/Level1.php index 6cf0ed7..facf9e3 100644 --- a/src/Expression/Level1.php +++ b/src/Expression/Level1.php @@ -34,7 +34,9 @@ private function __construct(Name $name) public static function of(Str $string): Maybe { /** @var Maybe */ - return Name::one($string)->map(static fn($name) => new self($name)); + return Name::one($string, Expansion::simple)->map( + static fn($name) => new self($name), + ); } /** diff --git a/src/Expression/Level2/Fragment.php b/src/Expression/Level2/Fragment.php index f7f80dc..1560945 100644 --- a/src/Expression/Level2/Fragment.php +++ b/src/Expression/Level2/Fragment.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, UrlEncode, Exception\OnlyScalarCanBeExpandedForExpression, }; @@ -35,7 +36,9 @@ private function __construct(Name $name) public static function of(Str $string): Maybe { /** @var Maybe */ - return Name::one($string, '#')->map(static fn($name) => new self($name)); + return Name::one($string, Expansion::fragment)->map( + static fn($name) => new self($name), + ); } public function expand(Map $variables): string diff --git a/src/Expression/Level2/Reserved.php b/src/Expression/Level2/Reserved.php index 5b6380d..a981729 100644 --- a/src/Expression/Level2/Reserved.php +++ b/src/Expression/Level2/Reserved.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, UrlEncode, Exception\OnlyScalarCanBeExpandedForExpression, }; @@ -35,7 +36,9 @@ private function __construct(Name $name) public static function of(Str $string): Maybe { /** @var Maybe */ - return Name::one($string, '+')->map(static fn($name) => new self($name)); + return Name::one($string, Expansion::reserved)->map( + static fn($name) => new self($name), + ); } /** diff --git a/src/Expression/Level3.php b/src/Expression/Level3.php index 768a102..07c5883 100644 --- a/src/Expression/Level3.php +++ b/src/Expression/Level3.php @@ -36,7 +36,9 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Name::many($string)->map(static fn($names) => new self($names)); + return Name::many($string, Expansion::simple)->map( + static fn($names) => new self($names), + ); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Fragment.php b/src/Expression/Level3/Fragment.php index 47dc608..a44ba31 100644 --- a/src/Expression/Level3/Fragment.php +++ b/src/Expression/Level3/Fragment.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, Expression\Level2, }; use Innmind\Immutable\{ @@ -41,7 +42,9 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Name::many($string, '#')->map(static fn($names) => new self($names)); + return Name::many($string, Expansion::fragment)->map( + static fn($names) => new self($names), + ); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Label.php b/src/Expression/Level3/Label.php index 65f5505..7e1815c 100644 --- a/src/Expression/Level3/Label.php +++ b/src/Expression/Level3/Label.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, Expression\Level1, }; use Innmind\Immutable\{ @@ -41,7 +42,9 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Name::many($string, '.')->map(static fn($names) => new self($names)); + return Name::many($string, Expansion::label)->map( + static fn($names) => new self($names), + ); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Parameters.php b/src/Expression/Level3/Parameters.php index af642c6..76003f2 100644 --- a/src/Expression/Level3/Parameters.php +++ b/src/Expression/Level3/Parameters.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, }; use Innmind\Immutable\{ Map, @@ -35,7 +36,9 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Name::many($string, ';')->map(static fn($names) => new self($names)); + return Name::many($string, Expansion::parameter)->map( + static fn($names) => new self($names), + ); } /** diff --git a/src/Expression/Level3/Path.php b/src/Expression/Level3/Path.php index 62fd155..e1de90c 100644 --- a/src/Expression/Level3/Path.php +++ b/src/Expression/Level3/Path.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, Expression\Level1, }; use Innmind\Immutable\{ @@ -41,7 +42,9 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Name::many($string, '/')->map(static fn($names) => new self($names)); + return Name::many($string, Expansion::path)->map( + static fn($names) => new self($names), + ); } public function expand(Map $variables): string diff --git a/src/Expression/Level3/Query.php b/src/Expression/Level3/Query.php index 06d6605..d045c6a 100644 --- a/src/Expression/Level3/Query.php +++ b/src/Expression/Level3/Query.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, }; use Innmind\Immutable\{ Map, @@ -35,7 +36,9 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Name::many($string, '?')->map(static fn($names) => new self($names)); + return Name::many($string, Expansion::query)->map( + static fn($names) => new self($names), + ); } /** diff --git a/src/Expression/Level3/QueryContinuation.php b/src/Expression/Level3/QueryContinuation.php index e9b2d6d..3032734 100644 --- a/src/Expression/Level3/QueryContinuation.php +++ b/src/Expression/Level3/QueryContinuation.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, }; use Innmind\Immutable\{ Map, @@ -35,7 +36,9 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Name::many($string, '&')->map(static fn($names) => new self($names)); + return Name::many($string, Expansion::queryContinuation)->map( + static fn($names) => new self($names), + ); } public static function named(Name $name): self diff --git a/src/Expression/Level3/Reserved.php b/src/Expression/Level3/Reserved.php index 8fa23bd..ad4cfa7 100644 --- a/src/Expression/Level3/Reserved.php +++ b/src/Expression/Level3/Reserved.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, Expression\Level2, }; use Innmind\Immutable\{ @@ -41,7 +42,9 @@ private function __construct(Sequence $names) public static function of(Str $string): Maybe { /** @var Maybe */ - return Name::many($string, '+')->map(static fn($names) => new self($names)); + return Name::many($string, Expansion::reserved)->map( + static fn($names) => new self($names), + ); } public function expand(Map $variables): string diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index a26ec29..bca0b2c 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -45,6 +45,7 @@ public static function of(Str $string): Maybe static fn(Name $name) => new self($name), self::explode(...), self::limit(...), + Expansion::simple, ); } diff --git a/src/Expression/Level4/Fragment.php b/src/Expression/Level4/Fragment.php index d92d12b..8a5b3df 100644 --- a/src/Expression/Level4/Fragment.php +++ b/src/Expression/Level4/Fragment.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, Expression\Level2, Expression\Level4, Exception\DomainException, @@ -41,7 +42,7 @@ public static function of(Str $string): Maybe static fn(Name $name) => new self($name), self::explode(...), self::limit(...), - '#', + Expansion::fragment, ); } diff --git a/src/Expression/Level4/Label.php b/src/Expression/Level4/Label.php index 5b92af2..688a6a6 100644 --- a/src/Expression/Level4/Label.php +++ b/src/Expression/Level4/Label.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, Expression\Level1, Expression\Level4, Exception\DomainException, @@ -38,7 +39,7 @@ public static function of(Str $string): Maybe static fn(Name $name) => new self($name), self::explode(...), self::limit(...), - '.', + Expansion::label, ); } diff --git a/src/Expression/Level4/Parameters.php b/src/Expression/Level4/Parameters.php index ffbabab..75dd1f7 100644 --- a/src/Expression/Level4/Parameters.php +++ b/src/Expression/Level4/Parameters.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, Expression\Level1, Expression\Level3, Expression\Level4, @@ -46,7 +47,7 @@ public static function of(Str $string): Maybe static fn(Name $name) => new self($name), self::explode(...), self::limit(...), - ';', + Expansion::parameter, ); } diff --git a/src/Expression/Level4/Parse.php b/src/Expression/Level4/Parse.php index 8141496..bbe0948 100644 --- a/src/Expression/Level4/Parse.php +++ b/src/Expression/Level4/Parse.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, }; use Innmind\Immutable\{ Str, @@ -20,7 +21,6 @@ final class Parse * @param pure-callable(Name): Expression $standard * @param pure-callable(Name): Expression $explode * @param pure-callable(Name, positive-int): Expression $limit - * @param ?non-empty-string $lead * * @return Maybe */ @@ -29,44 +29,42 @@ public static function of( callable $standard, callable $explode, callable $limit, - string $lead = null, + Expansion $expansion, ): Maybe { - return Name::one($string, $lead) + return Name::one($string, $expansion) ->map($standard) - ->otherwise(static fn() => self::explode($string, $explode, $lead)) - ->otherwise(static fn() => self::limit($string, $limit, $lead)); + ->otherwise(static fn() => self::explode($string, $explode, $expansion)) + ->otherwise(static fn() => self::limit($string, $limit, $expansion)); } /** * @psalm-pure * * @param pure-callable(Name): Expression $explode - * @param ?non-empty-string $lead * * @return Maybe */ private static function explode( Str $string, callable $explode, - string $lead = null, + Expansion $expansion, ): Maybe { - return Name::explode($string, $lead)->map($explode); + return Name::explode($string, $expansion)->map($explode); } /** * @psalm-pure * * @param pure-callable(Name, positive-int): Expression $limit - * @param ?non-empty-string $lead * * @return Maybe */ private static function limit( Str $string, callable $limit, - string $lead = null, + Expansion $expansion, ): Maybe { - return Name::limit($string, $lead)->map( + return Name::limit($string, $expansion)->map( static fn($tuple) => $limit($tuple[0], $tuple[1]), ); } diff --git a/src/Expression/Level4/Path.php b/src/Expression/Level4/Path.php index 3065c28..96287e6 100644 --- a/src/Expression/Level4/Path.php +++ b/src/Expression/Level4/Path.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, Expression\Level1, Expression\Level4, Exception\DomainException, @@ -38,7 +39,7 @@ public static function of(Str $string): Maybe static fn(Name $name) => new self($name), self::explode(...), self::limit(...), - '/', + Expansion::path, ); } diff --git a/src/Expression/Level4/Query.php b/src/Expression/Level4/Query.php index 3f337e1..f40fd99 100644 --- a/src/Expression/Level4/Query.php +++ b/src/Expression/Level4/Query.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, Expression\Level1, Expression\Level3, Expression\Level4, @@ -46,7 +47,7 @@ public static function of(Str $string): Maybe static fn(Name $name) => new self($name), self::explode(...), self::limit(...), - '?', + Expansion::query, ); } diff --git a/src/Expression/Level4/QueryContinuation.php b/src/Expression/Level4/QueryContinuation.php index b18998b..225e735 100644 --- a/src/Expression/Level4/QueryContinuation.php +++ b/src/Expression/Level4/QueryContinuation.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, Expression\Level1, Expression\Level3, Expression\Level4, @@ -46,7 +47,7 @@ public static function of(Str $string): Maybe static fn(Name $name) => new self($name), self::explode(...), self::limit(...), - '&', + Expansion::queryContinuation, ); } diff --git a/src/Expression/Level4/Reserved.php b/src/Expression/Level4/Reserved.php index 03985ba..a0a67af 100644 --- a/src/Expression/Level4/Reserved.php +++ b/src/Expression/Level4/Reserved.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, Expression\Level2, Expression\Level4, Exception\DomainException, @@ -46,7 +47,7 @@ public static function of(Str $string): Maybe static fn(Name $name) => new self($name), self::explode(...), self::limit(...), - '+', + Expansion::reserved, ); } diff --git a/src/Expression/Name.php b/src/Expression/Name.php index 251cf12..2534d40 100644 --- a/src/Expression/Name.php +++ b/src/Expression/Name.php @@ -37,15 +37,15 @@ public static function of(string $value): self /** * @psalm-pure * - * @param ?non-empty-string $lead - * * @return Maybe */ public static function one( Str $value, - string $lead = null, + Expansion $expansion, ): Maybe { - return self::find($value, $lead) + return Maybe::just($value) + ->filter($expansion->matches(...)) + ->map($expansion->clean(...)) ->map(static fn($value) => $value->toString()) ->map(static fn($value) => new self($value)); } @@ -53,15 +53,15 @@ public static function one( /** * @psalm-pure * - * @param ?non-empty-string $lead - * * @return Maybe */ public static function explode( Str $value, - string $lead = null, + Expansion $expansion, ): Maybe { - return self::find($value, $lead, '\\*') + return Maybe::just($value) + ->filter($expansion->matchesExplode(...)) + ->map($expansion->cleanExplode(...)) ->map(static fn($value) => $value->toString()) ->map(static fn($value) => new self($value)); } @@ -69,15 +69,15 @@ public static function explode( /** * @psalm-pure * - * @param ?non-empty-string $lead - * * @return Maybe */ public static function limit( Str $value, - string $lead = null, + Expansion $expansion, ): Maybe { - return self::find($value, $lead, ':\d+') + return Maybe::just($value) + ->filter($expansion->matchesLimit(...)) + ->map($expansion->clean(...)) ->map(static fn($value) => $value->split(':')) ->map(static fn($pieces) => $pieces->map(static fn($piece) => $piece->toString())) ->flatMap( @@ -98,28 +98,18 @@ public static function limit( /** * @psalm-pure * - * @param ?non-empty-string $lead - * * @return Maybe> */ public static function many( Str $value, - string $lead = null, + Expansion $expansion, ): Maybe { - $drop = match ($lead) { - null => 1, - default => 2, - }; - $lead = match ($lead) { - null => '', - default => "\\$lead", - }; - return Maybe::just($value) - ->filter(static fn($value) => $value->matches("~^\{{$lead}[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}\$~")) - ->map(static fn($value) => $value->drop($drop)->dropEnd(1)->split(',')) + ->filter($expansion->matchesMany(...)) + ->map($expansion->clean(...)) ->map( - static fn($values) => $values + static fn($value) => $value + ->split(',') ->map(static fn($value) => $value->toString()) ->map(static fn($value) => new self($value)), ); @@ -129,35 +119,4 @@ public function toString(): string { return $this->value; } - - /** - * @psalm-pure - * - * @param ?non-empty-string $lead - * @param ?non-empty-string $extra - * - * @return Maybe - */ - private static function find( - Str $value, - string $lead = null, - string $extra = null, - ): Maybe { - $drop = match ($lead) { - null => 1, - default => 2, - }; - $dropEnd = match ($extra) { - '\\*' => 2, - default => 1, - }; - $lead = match ($lead) { - null => '', - default => "\\$lead", - }; - - return Maybe::just($value) - ->filter(static fn($value) => $value->matches("~^\{{$lead}[a-zA-Z0-9_]+{$extra}\}\$~")) - ->map(static fn($value) => $value->drop($drop)->dropEnd($dropEnd)); - } } From d5bfc5f6ffe81eab11d3a2174548017881cc5031 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 17:18:01 +0200 Subject: [PATCH 21/39] deduplicate the allowed characters in an expression name --- src/Expression/Expansion.php | 25 +++++++++++++++++++++---- src/Expression/Name.php | 12 +++++++++++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/Expression/Expansion.php b/src/Expression/Expansion.php index ed75491..93c3184 100644 --- a/src/Expression/Expansion.php +++ b/src/Expression/Expansion.php @@ -36,22 +36,39 @@ public function cleanExplode(Str $value): Str public function matches(Str $value): bool { - return $value->matches("~^\{{$this->regex()}[a-zA-Z0-9_]+\}\$~"); + return $value->matches(\sprintf( + '~^\{%s%s\}$~', + $this->regex(), + Name::characters(), + )); } public function matchesExplode(Str $value): bool { - return $value->matches("~^\{{$this->regex()}[a-zA-Z0-9_]+\*\}\$~"); + return $value->matches(\sprintf( + '~^\{%s%s\*\}$~', + $this->regex(), + Name::characters(), + )); } public function matchesLimit(Str $value): bool { - return $value->matches("~^\{{$this->regex()}[a-zA-Z0-9_]+:\d+\}\$~"); + return $value->matches(\sprintf( + '~^\{%s%s:\d+\}$~', + $this->regex(), + Name::characters(), + )); } public function matchesMany(Str $value): bool { - return $value->matches("~^\{{$this->regex()}[a-zA-Z0-9_]+(,[a-zA-Z0-9_]+)*\}\$~"); + return $value->matches(\sprintf( + '~^\{%s%s(,%s)*\}$~', + $this->regex(), + Name::characters(), + Name::characters(), + )); } private function regex(): string diff --git a/src/Expression/Name.php b/src/Expression/Name.php index 2534d40..6e93109 100644 --- a/src/Expression/Name.php +++ b/src/Expression/Name.php @@ -27,7 +27,9 @@ private function __construct(string $value) */ public static function of(string $value): self { - if (!Str::of($value)->matches('~[a-zA-Z0-9_]+~')) { + $characters = self::characters(); + + if (!Str::of($value)->matches("~{$characters}~")) { throw new DomainException($value); } @@ -115,6 +117,14 @@ public static function many( ); } + /** + * @psalm-pure + */ + public static function characters(): string + { + return '[a-zA-Z0-9_]+'; + } + public function toString(): string { return $this->value; From 31bb790974179aa8a4feb1e7a6a037c7d4210b8d Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 17:20:22 +0200 Subject: [PATCH 22/39] fix allowed names --- src/Expression/Name.php | 2 +- tests/Expression/NameTest.php | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Expression/Name.php b/src/Expression/Name.php index 6e93109..dfba060 100644 --- a/src/Expression/Name.php +++ b/src/Expression/Name.php @@ -29,7 +29,7 @@ public static function of(string $value): self { $characters = self::characters(); - if (!Str::of($value)->matches("~{$characters}~")) { + if (!Str::of($value)->matches("~^{$characters}\$~")) { throw new DomainException($value); } diff --git a/tests/Expression/NameTest.php b/tests/Expression/NameTest.php index 57a329a..76a1cef 100644 --- a/tests/Expression/NameTest.php +++ b/tests/Expression/NameTest.php @@ -21,9 +21,12 @@ public function testInterface() { $this ->forAll( - Set\Strings::atLeast(1)->filter(static function(string $string): bool { - return (bool) \preg_match('~[a-zA-Z0-9_]+~', $string); - }), + Set\Strings::madeOf( + Set\Chars::lowercaseLetter(), + Set\Chars::uppercaseLetter(), + Set\Chars::number(), + Set\Elements::of('_'), + )->atLeast(1), ) ->then(function(string $string): void { $this->assertSame($string, Name::of($string)->toString()); @@ -35,7 +38,7 @@ public function testThrowWhenInvalidName() $this ->forAll( Set\Strings::any()->filter(static function(string $string): bool { - return (bool) !\preg_match('~[a-zA-Z0-9_]+~', $string); + return (bool) !\preg_match('~^[a-zA-Z0-9_]+$~', $string); }), ) ->then(function(string $string): void { From 0ec13c7cb833720b9b4ed4c9f85f648444a94a69 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 17:25:50 +0200 Subject: [PATCH 23/39] use enum instead of literal strings --- src/Expression/Expansion.php | 16 ++++++++++++---- src/Expression/Level3/NamedValues.php | 11 ++++++----- src/Expression/Level3/Parameters.php | 2 +- src/Expression/Level3/Query.php | 2 +- src/Expression/Level3/QueryContinuation.php | 2 +- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/Expression/Expansion.php b/src/Expression/Expansion.php index 93c3184..e7b9888 100644 --- a/src/Expression/Expansion.php +++ b/src/Expression/Expansion.php @@ -71,15 +71,15 @@ public function matchesMany(Str $value): bool )); } - private function regex(): string + public function continuation(): self { return match ($this) { - self::simple => '', - default => '\\'.$this->toString(), + self::query => self::queryContinuation, + default => $this, }; } - private function toString(): string + public function toString(): string { return match ($this) { self::simple => '', @@ -92,4 +92,12 @@ private function toString(): string self::queryContinuation => '&', }; } + + private function regex(): string + { + return match ($this) { + self::simple => '', + default => '\\'.$this->toString(), + }; + } } diff --git a/src/Expression/Level3/NamedValues.php b/src/Expression/Level3/NamedValues.php index 0124ab7..99234de 100644 --- a/src/Expression/Level3/NamedValues.php +++ b/src/Expression/Level3/NamedValues.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, Expression\Level1, }; use Innmind\Immutable\{ @@ -31,10 +32,10 @@ final class NamedValues implements Expression /** * @param Sequence $names */ - public function __construct(string $lead, string $separator, Sequence $names) + public function __construct(Expansion $expansion, Sequence $names) { - $this->lead = $lead; - $this->separator = $separator; + $this->lead = $expansion->toString(); + $this->separator = $expansion->continuation()->toString(); $this->names = $names; /** @var Map */ $this->expressions = Map::of( @@ -61,9 +62,9 @@ public static function of(Str $string): Maybe * * @param Sequence $names */ - public static function keyOnlyWhenEmpty(string $lead, string $separator, Sequence $names): self + public static function keyOnlyWhenEmpty(Expansion $expansion, Sequence $names): self { - $self = new self($lead, $separator, $names); + $self = new self($expansion, $names); $self->keyOnlyWhenEmpty = true; return $self; diff --git a/src/Expression/Level3/Parameters.php b/src/Expression/Level3/Parameters.php index 76003f2..35e4f2f 100644 --- a/src/Expression/Level3/Parameters.php +++ b/src/Expression/Level3/Parameters.php @@ -27,7 +27,7 @@ final class Parameters implements Expression */ private function __construct(Sequence $names) { - $this->expression = NamedValues::keyOnlyWhenEmpty(';', ';', $names); + $this->expression = NamedValues::keyOnlyWhenEmpty(Expansion::parameter, $names); } /** diff --git a/src/Expression/Level3/Query.php b/src/Expression/Level3/Query.php index d045c6a..6c88931 100644 --- a/src/Expression/Level3/Query.php +++ b/src/Expression/Level3/Query.php @@ -27,7 +27,7 @@ final class Query implements Expression */ private function __construct(Sequence $names) { - $this->expression = new NamedValues('?', '&', $names); + $this->expression = new NamedValues(Expansion::query, $names); } /** diff --git a/src/Expression/Level3/QueryContinuation.php b/src/Expression/Level3/QueryContinuation.php index 3032734..639ecd3 100644 --- a/src/Expression/Level3/QueryContinuation.php +++ b/src/Expression/Level3/QueryContinuation.php @@ -27,7 +27,7 @@ final class QueryContinuation implements Expression */ private function __construct(Sequence $names) { - $this->expression = new NamedValues('&', '&', $names); + $this->expression = new NamedValues(Expansion::queryContinuation, $names); } /** From c68bac3c65e413037ab036927885cfa17420c582 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 17:33:33 +0200 Subject: [PATCH 24/39] use an enum instead of literal strings --- src/Expression/Expansion.php | 16 ++++++++-------- src/Expression/Level4.php | 21 +++++++++++---------- src/Expression/Level4/Fragment.php | 6 +++--- src/Expression/Level4/Label.php | 6 +++--- src/Expression/Level4/Path.php | 6 +++--- 5 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/Expression/Expansion.php b/src/Expression/Expansion.php index e7b9888..9d303cb 100644 --- a/src/Expression/Expansion.php +++ b/src/Expression/Expansion.php @@ -79,6 +79,14 @@ public function continuation(): self }; } + public function regex(): string + { + return match ($this) { + self::simple => '', + default => '\\'.$this->toString(), + }; + } + public function toString(): string { return match ($this) { @@ -92,12 +100,4 @@ public function toString(): string self::queryContinuation => '&', }; } - - private function regex(): string - { - return match ($this) { - self::simple => '', - default => '\\'.$this->toString(), - }; - } } diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index bca0b2c..318b428 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -26,13 +26,14 @@ final class Level4 implements Expression /** @var ?positive-int */ private ?int $limit = null; private bool $explode = false; - private string $lead = ''; + private Expansion $expansion; private string $separator = ','; private function __construct(Name $name) { $this->name = $name; $this->expression = Level1::named($name); + $this->expansion = Expansion::simple; } /** @@ -93,10 +94,10 @@ public function add(Str $pattern): Composite ); } - public function withLead(string $lead): self + public function withExpansion(Expansion $expansion): self { $self = clone $this; - $self->lead = $lead; + $self->expansion = $expansion; return $self; } @@ -152,7 +153,7 @@ public function expand(Map $variables): string $value = $this->expression->expand($variables); } - return "{$this->lead}$value"; + return "{$this->expansion->toString()}$value"; } public function regex(): string @@ -173,7 +174,7 @@ public function regex(): string return \sprintf( '%s%s', - $this->lead ? '\\'.$this->lead : '', + $this->expansion->regex(), $regex, ); } @@ -181,14 +182,14 @@ public function regex(): string public function toString(): string { if ($this->mustLimit()) { - return "{{$this->lead}{$this->name->toString()}:{$this->limit}}"; + return "{{$this->expansion->toString()}{$this->name->toString()}:{$this->limit}}"; } if ($this->explode) { - return "{{$this->lead}{$this->name->toString()}*}"; + return "{{$this->expansion->toString()}{$this->name->toString()}*}"; } - return "{{$this->lead}{$this->name->toString()}}"; + return "{{$this->expansion->toString()}{$this->name->toString()}}"; } /** @@ -234,7 +235,7 @@ function($variableToExpand) use ($variables): string { return Str::of($this->separator) ->join($expanded) - ->prepend($this->lead) + ->prepend($this->expansion->toString()) ->toString(); } @@ -272,7 +273,7 @@ function($variableToExpand) use ($variables): string { return Str::of($this->separator) ->join($expanded) - ->prepend($this->lead) + ->prepend($this->expansion->toString()) ->toString(); } } diff --git a/src/Expression/Level4/Fragment.php b/src/Expression/Level4/Fragment.php index 8a5b3df..99021c6 100644 --- a/src/Expression/Level4/Fragment.php +++ b/src/Expression/Level4/Fragment.php @@ -28,7 +28,7 @@ final class Fragment implements Expression private function __construct(Name $name) { $this->expression = Level4::named($name) - ->withLead('#') + ->withExpansion(Expansion::fragment) ->withExpression(Level2\Reserved::named(...)); } @@ -55,7 +55,7 @@ public static function limit(Name $name, int $limit): self { $self = new self($name); $self->expression = Level4::limit($name, $limit) - ->withLead('#') + ->withExpansion(Expansion::fragment) ->withExpression(Level2\Reserved::named(...)); return $self; @@ -68,7 +68,7 @@ public static function explode(Name $name): self { $self = new self($name); $self->expression = Level4::explode($name) - ->withLead('#') + ->withExpansion(Expansion::fragment) ->withExpression(Level2\Reserved::named(...)); return $self; diff --git a/src/Expression/Level4/Label.php b/src/Expression/Level4/Label.php index 688a6a6..6c974a5 100644 --- a/src/Expression/Level4/Label.php +++ b/src/Expression/Level4/Label.php @@ -26,7 +26,7 @@ final class Label implements Expression private function __construct(Name $name) { - $this->expression = Level4::named($name)->withLead('.'); + $this->expression = Level4::named($name)->withExpansion(Expansion::label); } /** @@ -51,7 +51,7 @@ public static function of(Str $string): Maybe public static function limit(Name $name, int $limit): self { $self = new self($name); - $self->expression = Level4::limit($name, $limit)->withLead('.'); + $self->expression = Level4::limit($name, $limit)->withExpansion(Expansion::label); return $self; } @@ -63,7 +63,7 @@ public static function explode(Name $name): self { $self = new self($name); $self->expression = Level4::explode($name) - ->withLead('.') + ->withExpansion(Expansion::label) ->withSeparator('.'); return $self; diff --git a/src/Expression/Level4/Path.php b/src/Expression/Level4/Path.php index 96287e6..173e729 100644 --- a/src/Expression/Level4/Path.php +++ b/src/Expression/Level4/Path.php @@ -26,7 +26,7 @@ final class Path implements Expression private function __construct(Name $name) { - $this->expression = Level4::named($name)->withLead('/'); + $this->expression = Level4::named($name)->withExpansion(Expansion::path); } /** @@ -51,7 +51,7 @@ public static function of(Str $string): Maybe public static function limit(Name $name, int $limit): self { $self = new self($name); - $self->expression = Level4::limit($name, $limit)->withLead('/'); + $self->expression = Level4::limit($name, $limit)->withExpansion(Expansion::path); return $self; } @@ -63,7 +63,7 @@ public static function explode(Name $name): self { $self = new self($name); $self->expression = Level4::explode($name) - ->withLead('/') + ->withExpansion(Expansion::path) ->withSeparator('/'); return $self; From 252d20b085216515bdbd7bbb372596e4032cdfce Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 17:41:55 +0200 Subject: [PATCH 25/39] determine the separator to use based on the expansion --- src/Expression/Expansion.php | 9 +++++++++ src/Expression/Level4.php | 10 +++------- src/Expression/Level4/Label.php | 3 +-- src/Expression/Level4/Path.php | 3 +-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/Expression/Expansion.php b/src/Expression/Expansion.php index 9d303cb..bbc3362 100644 --- a/src/Expression/Expansion.php +++ b/src/Expression/Expansion.php @@ -79,6 +79,15 @@ public function continuation(): self }; } + public function explodeSeparator(): string + { + return match ($this) { + self::label => '.', + self::path => '/', + default => ',', + }; + } + public function regex(): string { return match ($this) { diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index 318b428..c35475b 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -99,13 +99,9 @@ public function withExpansion(Expansion $expansion): self $self = clone $this; $self->expansion = $expansion; - return $self; - } - - public function withSeparator(string $separator): self - { - $self = clone $this; - $self->separator = $separator; + if ($this->explode) { + $self->separator = $expansion->explodeSeparator(); + } return $self; } diff --git a/src/Expression/Level4/Label.php b/src/Expression/Level4/Label.php index 6c974a5..dd16c2d 100644 --- a/src/Expression/Level4/Label.php +++ b/src/Expression/Level4/Label.php @@ -63,8 +63,7 @@ public static function explode(Name $name): self { $self = new self($name); $self->expression = Level4::explode($name) - ->withExpansion(Expansion::label) - ->withSeparator('.'); + ->withExpansion(Expansion::label); return $self; } diff --git a/src/Expression/Level4/Path.php b/src/Expression/Level4/Path.php index 173e729..c8f8d9d 100644 --- a/src/Expression/Level4/Path.php +++ b/src/Expression/Level4/Path.php @@ -63,8 +63,7 @@ public static function explode(Name $name): self { $self = new self($name); $self->expression = Level4::explode($name) - ->withExpansion(Expansion::path) - ->withSeparator('/'); + ->withExpansion(Expansion::path); return $self; } From 66ab91dd3b6ce6b6e8cb477b02183ec07dccd0aa Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 17:45:24 +0200 Subject: [PATCH 26/39] no need to keep the separator in memory --- src/Expression/Level4.php | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index c35475b..f0697fa 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -27,7 +27,6 @@ final class Level4 implements Expression private ?int $limit = null; private bool $explode = false; private Expansion $expansion; - private string $separator = ','; private function __construct(Name $name) { @@ -99,10 +98,6 @@ public function withExpansion(Expansion $expansion): self $self = clone $this; $self->expansion = $expansion; - if ($this->explode) { - $self->separator = $expansion->explodeSeparator(); - } - return $self; } @@ -229,7 +224,7 @@ function($variableToExpand) use ($variables): string { }, ); - return Str::of($this->separator) + return $this->separator() ->join($expanded) ->prepend($this->expansion->toString()) ->toString(); @@ -267,9 +262,22 @@ function($variableToExpand) use ($variables): string { }, ); - return Str::of($this->separator) + return $this->separator() ->join($expanded) ->prepend($this->expansion->toString()) ->toString(); } + + private function separator(): Str + { + if (!$this->explode) { + return Str::of(','); + } + + return Str::of(match ($this->expansion) { + Expansion::label => '.', + Expansion::path => '/', + default => ',', + }); + } } From b12b3dc6ea1f85f80d112df663f978b72954e5b2 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 17:48:29 +0200 Subject: [PATCH 27/39] no need to keep the lead and separator characters in memory --- src/Expression/Level3/NamedValues.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Expression/Level3/NamedValues.php b/src/Expression/Level3/NamedValues.php index 99234de..a57cfc8 100644 --- a/src/Expression/Level3/NamedValues.php +++ b/src/Expression/Level3/NamedValues.php @@ -21,8 +21,7 @@ */ final class NamedValues implements Expression { - private string $lead; - private string $separator; + private Expansion $expansion; /** @var Sequence */ private Sequence $names; /** @var Map */ @@ -34,8 +33,7 @@ final class NamedValues implements Expression */ public function __construct(Expansion $expansion, Sequence $names) { - $this->lead = $expansion->toString(); - $this->separator = $expansion->continuation()->toString(); + $this->expansion = $expansion; $this->names = $names; /** @var Map */ $this->expressions = Map::of( @@ -86,15 +84,15 @@ function(Sequence $expanded, string $name, Expression $expression) use ($variabl }, ); - return Str::of($this->separator) + return Str::of($this->expansion->continuation()->toString()) ->join($expanded) - ->prepend($this->lead) + ->prepend($this->expansion->toString()) ->toString(); } public function regex(): string { - return Str::of('\\'.$this->separator) + return Str::of($this->expansion->continuation()->regex()) ->join($this->names->map( fn($name) => \sprintf( '%s=%s%s', @@ -103,7 +101,7 @@ public function regex(): string Level1::named($name)->regex(), ), )) - ->prepend('\\'.$this->lead) + ->prepend($this->expansion->regex()) ->toString(); } @@ -113,7 +111,7 @@ public function toString(): string ->join($this->names->map( static fn($element) => $element->toString(), )) - ->prepend('{'.$this->lead) + ->prepend('{'.$this->expansion->toString()) ->append('}') ->toString(); } From 89219dba064270fc8669566c7591edfb6fa917cc Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 17:58:01 +0200 Subject: [PATCH 28/39] remove duplicated code --- src/Expression/Level4.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index f0697fa..6c44bdc 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -274,10 +274,6 @@ private function separator(): Str return Str::of(','); } - return Str::of(match ($this->expansion) { - Expansion::label => '.', - Expansion::path => '/', - default => ',', - }); + return Str::of($this->expansion->explodeSeparator()); } } From 5351d44368e6884848baafd0360b09c8a67bfa3e Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 18:00:10 +0200 Subject: [PATCH 29/39] force each expression to expose its expansion --- src/Expression.php | 2 ++ src/Expression/Level1.php | 5 +++++ src/Expression/Level2/Fragment.php | 5 +++++ src/Expression/Level2/Reserved.php | 5 +++++ src/Expression/Level3.php | 5 +++++ src/Expression/Level3/Fragment.php | 5 +++++ src/Expression/Level3/Label.php | 5 +++++ src/Expression/Level3/NamedValues.php | 5 +++++ src/Expression/Level3/Parameters.php | 5 +++++ src/Expression/Level3/Path.php | 5 +++++ src/Expression/Level3/Query.php | 5 +++++ src/Expression/Level3/QueryContinuation.php | 5 +++++ src/Expression/Level3/Reserved.php | 5 +++++ src/Expression/Level4.php | 5 +++++ src/Expression/Level4/Composite.php | 8 ++++++++ src/Expression/Level4/Fragment.php | 5 +++++ src/Expression/Level4/Label.php | 5 +++++ src/Expression/Level4/Parameters.php | 5 +++++ src/Expression/Level4/Path.php | 5 +++++ src/Expression/Level4/Query.php | 5 +++++ src/Expression/Level4/QueryContinuation.php | 5 +++++ src/Expression/Level4/Reserved.php | 5 +++++ 22 files changed, 110 insertions(+) diff --git a/src/Expression.php b/src/Expression.php index 2397534..c2aa01b 100644 --- a/src/Expression.php +++ b/src/Expression.php @@ -21,6 +21,8 @@ interface Expression */ public static function of(Str $string): Maybe; + public function expansion(): Expression\Expansion; + /** * @param Map $variables */ diff --git a/src/Expression/Level1.php b/src/Expression/Level1.php index facf9e3..764ddb2 100644 --- a/src/Expression/Level1.php +++ b/src/Expression/Level1.php @@ -47,6 +47,11 @@ public static function named(Name $name): self return new self($name); } + public function expansion(): Expansion + { + return Expansion::simple; + } + public function expand(Map $variables): string { return $variables diff --git a/src/Expression/Level2/Fragment.php b/src/Expression/Level2/Fragment.php index 1560945..09d3d3d 100644 --- a/src/Expression/Level2/Fragment.php +++ b/src/Expression/Level2/Fragment.php @@ -41,6 +41,11 @@ public static function of(Str $string): Maybe ); } + public function expansion(): Expansion + { + return Expansion::fragment; + } + public function expand(Map $variables): string { return $variables diff --git a/src/Expression/Level2/Reserved.php b/src/Expression/Level2/Reserved.php index a981729..c57ab5a 100644 --- a/src/Expression/Level2/Reserved.php +++ b/src/Expression/Level2/Reserved.php @@ -49,6 +49,11 @@ public static function named(Name $name): self return new self($name); } + public function expansion(): Expansion + { + return Expansion::reserved; + } + public function expand(Map $variables): string { return $variables diff --git a/src/Expression/Level3.php b/src/Expression/Level3.php index 07c5883..f0295a1 100644 --- a/src/Expression/Level3.php +++ b/src/Expression/Level3.php @@ -41,6 +41,11 @@ public static function of(Str $string): Maybe ); } + public function expansion(): Expansion + { + return Expansion::simple; + } + public function expand(Map $variables): string { $expanded = $this->expressions->map( diff --git a/src/Expression/Level3/Fragment.php b/src/Expression/Level3/Fragment.php index a44ba31..d629e9a 100644 --- a/src/Expression/Level3/Fragment.php +++ b/src/Expression/Level3/Fragment.php @@ -47,6 +47,11 @@ public static function of(Str $string): Maybe ); } + public function expansion(): Expansion + { + return Expansion::fragment; + } + public function expand(Map $variables): string { $expanded = $this->expressions->map( diff --git a/src/Expression/Level3/Label.php b/src/Expression/Level3/Label.php index 7e1815c..b67af13 100644 --- a/src/Expression/Level3/Label.php +++ b/src/Expression/Level3/Label.php @@ -47,6 +47,11 @@ public static function of(Str $string): Maybe ); } + public function expansion(): Expansion + { + return Expansion::label; + } + public function expand(Map $variables): string { $expanded = $this->expressions->map( diff --git a/src/Expression/Level3/NamedValues.php b/src/Expression/Level3/NamedValues.php index a57cfc8..be87e8a 100644 --- a/src/Expression/Level3/NamedValues.php +++ b/src/Expression/Level3/NamedValues.php @@ -68,6 +68,11 @@ public static function keyOnlyWhenEmpty(Expansion $expansion, Sequence $names): return $self; } + public function expansion(): Expansion + { + return $this->expansion; + } + public function expand(Map $variables): string { /** @var Sequence */ diff --git a/src/Expression/Level3/Parameters.php b/src/Expression/Level3/Parameters.php index 35e4f2f..140a7b8 100644 --- a/src/Expression/Level3/Parameters.php +++ b/src/Expression/Level3/Parameters.php @@ -49,6 +49,11 @@ public static function named(Name $name): self return new self(Sequence::of($name)); } + public function expansion(): Expansion + { + return Expansion::parameter; + } + public function expand(Map $variables): string { return $this->expression->expand($variables); diff --git a/src/Expression/Level3/Path.php b/src/Expression/Level3/Path.php index e1de90c..20b1bdf 100644 --- a/src/Expression/Level3/Path.php +++ b/src/Expression/Level3/Path.php @@ -47,6 +47,11 @@ public static function of(Str $string): Maybe ); } + public function expansion(): Expansion + { + return Expansion::path; + } + public function expand(Map $variables): string { return Str::of('/') diff --git a/src/Expression/Level3/Query.php b/src/Expression/Level3/Query.php index 6c88931..d821a3e 100644 --- a/src/Expression/Level3/Query.php +++ b/src/Expression/Level3/Query.php @@ -49,6 +49,11 @@ public static function named(Name $name): self return new self(Sequence::of($name)); } + public function expansion(): Expansion + { + return Expansion::query; + } + public function expand(Map $variables): string { return $this->expression->expand($variables); diff --git a/src/Expression/Level3/QueryContinuation.php b/src/Expression/Level3/QueryContinuation.php index 639ecd3..6bc6ac0 100644 --- a/src/Expression/Level3/QueryContinuation.php +++ b/src/Expression/Level3/QueryContinuation.php @@ -46,6 +46,11 @@ public static function named(Name $name): self return new self(Sequence::of($name)); } + public function expansion(): Expansion + { + return Expansion::queryContinuation; + } + public function expand(Map $variables): string { return $this->expression->expand($variables); diff --git a/src/Expression/Level3/Reserved.php b/src/Expression/Level3/Reserved.php index ad4cfa7..ad929ab 100644 --- a/src/Expression/Level3/Reserved.php +++ b/src/Expression/Level3/Reserved.php @@ -47,6 +47,11 @@ public static function of(Str $string): Maybe ); } + public function expansion(): Expansion + { + return Expansion::reserved; + } + public function expand(Map $variables): string { $expanded = $this->expressions->map( diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index 6c44bdc..988e986 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -81,6 +81,11 @@ public static function named(Name $name): self return new self($name); } + public function expansion(): Expansion + { + return Expansion::simple; + } + public function add(Str $pattern): Composite { return new Composite( diff --git a/src/Expression/Level4/Composite.php b/src/Expression/Level4/Composite.php index 4a0d73b..7425815 100644 --- a/src/Expression/Level4/Composite.php +++ b/src/Expression/Level4/Composite.php @@ -6,6 +6,7 @@ use Innmind\UrlTemplate\{ Expression, Expression\Name, + Expression\Expansion, Expressions, }; use Innmind\Immutable\{ @@ -21,6 +22,7 @@ final class Composite implements Expression { private string $separator; + private Expression $first; /** @var Sequence */ private Sequence $expressions; private bool $removeLead = false; @@ -31,6 +33,7 @@ public function __construct( Expression ...$expressions, ) { $this->separator = $separator; + $this->first = $level4; $this->expressions = Sequence::of($level4, ...$expressions); } @@ -75,6 +78,11 @@ public static function of(Str $string): Maybe ); } + public function expansion(): Expansion + { + return $this->first->expansion(); + } + public function expand(Map $variables): string { $expanded = $this->expressions->map( diff --git a/src/Expression/Level4/Fragment.php b/src/Expression/Level4/Fragment.php index 99021c6..fb371fb 100644 --- a/src/Expression/Level4/Fragment.php +++ b/src/Expression/Level4/Fragment.php @@ -86,6 +86,11 @@ public function add(Str $pattern): Composite ); } + public function expansion(): Expansion + { + return Expansion::fragment; + } + public function regex(): string { return $this->expression->regex(); diff --git a/src/Expression/Level4/Label.php b/src/Expression/Level4/Label.php index dd16c2d..da7a45e 100644 --- a/src/Expression/Level4/Label.php +++ b/src/Expression/Level4/Label.php @@ -68,6 +68,11 @@ public static function explode(Name $name): self return $self; } + public function expansion(): Expansion + { + return Expansion::label; + } + public function add(Str $pattern): Composite { return new Composite( diff --git a/src/Expression/Level4/Parameters.php b/src/Expression/Level4/Parameters.php index 75dd1f7..754c2b9 100644 --- a/src/Expression/Level4/Parameters.php +++ b/src/Expression/Level4/Parameters.php @@ -75,6 +75,11 @@ public static function explode(Name $name): self return $self; } + public function expansion(): Expansion + { + return Expansion::parameter; + } + public function add(Str $pattern): Composite { return new Composite( diff --git a/src/Expression/Level4/Path.php b/src/Expression/Level4/Path.php index c8f8d9d..1e923e4 100644 --- a/src/Expression/Level4/Path.php +++ b/src/Expression/Level4/Path.php @@ -68,6 +68,11 @@ public static function explode(Name $name): self return $self; } + public function expansion(): Expansion + { + return Expansion::path; + } + public function add(Str $pattern): Composite { return new Composite( diff --git a/src/Expression/Level4/Query.php b/src/Expression/Level4/Query.php index f40fd99..5328aa9 100644 --- a/src/Expression/Level4/Query.php +++ b/src/Expression/Level4/Query.php @@ -75,6 +75,11 @@ public static function explode(Name $name): self return $self; } + public function expansion(): Expansion + { + return Expansion::query; + } + public function add(Str $pattern): Composite { return new Composite( diff --git a/src/Expression/Level4/QueryContinuation.php b/src/Expression/Level4/QueryContinuation.php index 225e735..cbc5507 100644 --- a/src/Expression/Level4/QueryContinuation.php +++ b/src/Expression/Level4/QueryContinuation.php @@ -75,6 +75,11 @@ public static function explode(Name $name): self return $self; } + public function expansion(): Expansion + { + return Expansion::queryContinuation; + } + public function add(Str $pattern): Composite { return new Composite( diff --git a/src/Expression/Level4/Reserved.php b/src/Expression/Level4/Reserved.php index a0a67af..6945d33 100644 --- a/src/Expression/Level4/Reserved.php +++ b/src/Expression/Level4/Reserved.php @@ -81,6 +81,11 @@ public static function explode(Name $name): self return $self; } + public function expansion(): Expansion + { + return Expansion::reserved; + } + public function add(Str $pattern): Composite { return new Composite( From 74ffdbd597aca85c8e053474369a6180d51b6d9d Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 18:49:08 +0200 Subject: [PATCH 30/39] fix parsing level 4 composite --- src/Expression/Expansion.php | 30 +++++++ src/Expression/Level4.php | 12 --- src/Expression/Level4/Composite.php | 89 +++++++++++---------- src/Expression/Level4/Fragment.php | 12 --- src/Expression/Level4/Label.php | 12 --- src/Expression/Level4/Parameters.php | 12 --- src/Expression/Level4/Path.php | 12 --- src/Expression/Level4/Query.php | 12 --- src/Expression/Level4/QueryContinuation.php | 12 --- src/Expression/Level4/Reserved.php | 12 --- tests/Expression/Level4/CompositeTest.php | 66 +++++---------- 11 files changed, 97 insertions(+), 184 deletions(-) diff --git a/src/Expression/Expansion.php b/src/Expression/Expansion.php index bbc3362..8d4c812 100644 --- a/src/Expression/Expansion.php +++ b/src/Expression/Expansion.php @@ -19,6 +19,18 @@ enum Expansion case query; case queryContinuation; + /** + * @psalm-pure + */ + public static function matchesLevel4(Str $value): bool + { + return $value->matches(\sprintf( + '~^\{[\+#\./;\?&]?%s(\*|:\d*)?(,%s(\*|:\d*)?)*\}$~', + Name::characters(), + Name::characters(), + )); + } + public function clean(Str $value): Str { $drop = match ($this) { @@ -79,6 +91,24 @@ public function continuation(): self }; } + public function separator(): string + { + return match ($this) { + self::simple => ',', + self::reserved => ',', + self::fragment => ',', + default => '', + }; + } + + public function separatorRegex(): string + { + return match ($this->separator()) { + '' => '', + ',' => '\\,', + }; + } + public function explodeSeparator(): string { return match ($this) { diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index 988e986..3101ad8 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -86,18 +86,6 @@ public function expansion(): Expansion return Expansion::simple; } - public function add(Str $pattern): Composite - { - return new Composite( - ',', - $this, - self::of($pattern->prepend('{')->append('}'))->match( - static fn($expression) => $expression, - static fn() => throw new DomainException('todo'), - ), - ); - } - public function withExpansion(Expansion $expansion): self { $self = clone $this; diff --git a/src/Expression/Level4/Composite.php b/src/Expression/Level4/Composite.php index 7425815..d5bdc8c 100644 --- a/src/Expression/Level4/Composite.php +++ b/src/Expression/Level4/Composite.php @@ -21,34 +21,17 @@ */ final class Composite implements Expression { - private string $separator; - private Expression $first; + private Expansion $expansion; /** @var Sequence */ private Sequence $expressions; - private bool $removeLead = false; - - public function __construct( - string $separator, - Expression $level4, - Expression ...$expressions, - ) { - $this->separator = $separator; - $this->first = $level4; - $this->expressions = Sequence::of($level4, ...$expressions); - } /** - * @psalm-pure + * @param Sequence $expressions */ - public static function removeLead( - string $separator, - Expression $level4, - Expression ...$expressions, - ): self { - $self = new self($separator, $level4, ...$expressions); - $self->removeLead = true; - - return $self; + private function __construct(Expansion $expansion, Sequence $expressions) + { + $this->expansion = $expansion; + $this->expressions = $expressions; } /** @@ -56,31 +39,29 @@ public static function removeLead( */ public static function of(Str $string): Maybe { - /** - * @psalm-suppress MixedInferredReturnType - * @psalm-suppress MixedReturnStatement - * @psalm-suppress UndefinedInterfaceMethod - */ + /** @var Maybe */ return Maybe::just($string) - ->filter(static fn($string) => $string->matches('~^\{[\+#\./;\?&]?[a-zA-Z0-9_]+(\*|:\d*)?(,[a-zA-Z0-9_]+(\*|:\d*)?)+\}$~')) - ->map(static fn($string) => $string->trim('{}')->split(',')) + ->filter(Expansion::matchesLevel4(...)) + ->map(Expansion::simple->clean(...)) + ->map(static fn($string) => $string->split(',')) ->flatMap( - static fn($pieces) => $pieces + static fn($expressions) => $expressions ->first() ->map(static fn($first) => $first->prepend('{')->append('}')) ->flatMap(Expressions::of(...)) - ->map( - static fn($first) => $pieces->drop(1)->reduce( - $first, - static fn(Expression $level4, $expression): Expression => $level4->add($expression), - ), + ->flatMap( + static fn($first) => self::parse($first, $expressions->drop(1)) + ->map(static fn($expressions) => new self( + $first->expansion(), + $expressions, + )), ), ); } public function expansion(): Expansion { - return $this->first->expansion(); + return $this->expansion; } public function expand(Map $variables): string @@ -96,7 +77,7 @@ public function expand(Map $variables): string ->take(1) ->append( $expanded->drop(1)->map(function(string $value): string { - if ($this->removeLead) { + if ($this->removeLead()) { return Str::of($value)->drop(1)->toString(); } @@ -104,7 +85,7 @@ public function expand(Map $variables): string }), ); - return Str::of($this->separator)->join($expanded)->toString(); + return Str::of($this->expansion()->separator())->join($expanded)->toString(); } public function regex(): string @@ -113,14 +94,14 @@ public function regex(): string ->expressions ->drop(1) ->map(function(Expression $expression): string { - if ($this->removeLead) { + if ($this->removeLead()) { return Str::of($expression->regex())->drop(2)->toString(); } return $expression->regex(); }); - return Str::of($this->separator ? '\\'.$this->separator : '') + return Str::of($this->expansion()->separatorRegex()) ->join( $this ->expressions @@ -157,4 +138,30 @@ public function toString(): string ->append('}') ->toString(); } + + /** + * @psalm-pure + * + * @param Sequence $expressions + * + * @return Maybe> + */ + private static function parse(Expression $first, Sequence $expressions): Maybe + { + /** @var Maybe> */ + return Maybe::all( + Maybe::just($first), + ...$expressions + ->map(static fn($expression) => $expression->prepend($first->expansion()->continuation()->toString())) + ->map(static fn($expression) => $expression->prepend('{')->append('}')) + ->map(Expressions::of(...)) + ->toList(), + ) + ->map(Sequence::of(...)); + } + + private function removeLead(): bool + { + return $this->expansion() === Expansion::fragment; + } } diff --git a/src/Expression/Level4/Fragment.php b/src/Expression/Level4/Fragment.php index fb371fb..e83e61b 100644 --- a/src/Expression/Level4/Fragment.php +++ b/src/Expression/Level4/Fragment.php @@ -74,18 +74,6 @@ public static function explode(Name $name): self return $self; } - public function add(Str $pattern): Composite - { - return Composite::removeLead( - ',', - $this, - self::of($pattern->prepend('{#')->append('}'))->match( - static fn($expression) => $expression, - static fn() => throw new DomainException('todo'), - ), - ); - } - public function expansion(): Expansion { return Expansion::fragment; diff --git a/src/Expression/Level4/Label.php b/src/Expression/Level4/Label.php index da7a45e..b8280c9 100644 --- a/src/Expression/Level4/Label.php +++ b/src/Expression/Level4/Label.php @@ -73,18 +73,6 @@ public function expansion(): Expansion return Expansion::label; } - public function add(Str $pattern): Composite - { - return new Composite( - '', - $this, - self::of($pattern->prepend('{.')->append('}'))->match( - static fn($expression) => $expression, - static fn() => throw new DomainException('todo'), - ), - ); - } - public function expand(Map $variables): string { return $this->expression->expand($variables); diff --git a/src/Expression/Level4/Parameters.php b/src/Expression/Level4/Parameters.php index 754c2b9..d2df453 100644 --- a/src/Expression/Level4/Parameters.php +++ b/src/Expression/Level4/Parameters.php @@ -80,18 +80,6 @@ public function expansion(): Expansion return Expansion::parameter; } - public function add(Str $pattern): Composite - { - return new Composite( - '', - $this, - self::of($pattern->prepend('{;')->append('}'))->match( - static fn($expression) => $expression, - static fn() => throw new DomainException('todo'), - ), - ); - } - /** * @param Map $variables */ diff --git a/src/Expression/Level4/Path.php b/src/Expression/Level4/Path.php index 1e923e4..096daea 100644 --- a/src/Expression/Level4/Path.php +++ b/src/Expression/Level4/Path.php @@ -73,18 +73,6 @@ public function expansion(): Expansion return Expansion::path; } - public function add(Str $pattern): Composite - { - return new Composite( - '', - $this, - self::of($pattern->prepend('{/')->append('}'))->match( - static fn($expression) => $expression, - static fn() => throw new DomainException('todo'), - ), - ); - } - public function expand(Map $variables): string { return $this->expression->expand($variables); diff --git a/src/Expression/Level4/Query.php b/src/Expression/Level4/Query.php index 5328aa9..756e6b8 100644 --- a/src/Expression/Level4/Query.php +++ b/src/Expression/Level4/Query.php @@ -80,18 +80,6 @@ public function expansion(): Expansion return Expansion::query; } - public function add(Str $pattern): Composite - { - return new Composite( - '', - $this, - QueryContinuation::of($pattern->prepend('{&')->append('}'))->match( - static fn($expression) => $expression, - static fn() => throw new DomainException('todo'), - ), - ); - } - /** * @param Map $variables */ diff --git a/src/Expression/Level4/QueryContinuation.php b/src/Expression/Level4/QueryContinuation.php index cbc5507..83ed244 100644 --- a/src/Expression/Level4/QueryContinuation.php +++ b/src/Expression/Level4/QueryContinuation.php @@ -80,18 +80,6 @@ public function expansion(): Expansion return Expansion::queryContinuation; } - public function add(Str $pattern): Composite - { - return new Composite( - '', - $this, - self::of($pattern->prepend('{&')->append('}'))->match( - static fn($expression) => $expression, - static fn() => throw new DomainException('todo'), - ), - ); - } - /** * @param Map $variables */ diff --git a/src/Expression/Level4/Reserved.php b/src/Expression/Level4/Reserved.php index 6945d33..70c1142 100644 --- a/src/Expression/Level4/Reserved.php +++ b/src/Expression/Level4/Reserved.php @@ -86,18 +86,6 @@ public function expansion(): Expansion return Expansion::reserved; } - public function add(Str $pattern): Composite - { - return new Composite( - ',', - $this, - self::of($pattern->prepend('{+')->append('}'))->match( - static fn($expression) => $expression, - static fn() => throw new DomainException('todo'), - ), - ); - } - public function expand(Map $variables): string { return $this->expression->expand($variables); diff --git a/tests/Expression/Level4/CompositeTest.php b/tests/Expression/Level4/CompositeTest.php index 618a162..a57b5d9 100644 --- a/tests/Expression/Level4/CompositeTest.php +++ b/tests/Expression/Level4/CompositeTest.php @@ -21,9 +21,9 @@ public function testInterface() { $this->assertInstanceOf( Expression::class, - new Composite( - '/', - $this->createMock(Expression::class), + Composite::of(Str::of('{var}'))->match( + static fn($expression) => $expression, + static fn() => null, ), ); } @@ -32,31 +32,17 @@ public function testStringCast() { $this->assertSame( '{/var:1,var}', - (new Composite( - '/', - Path::of(Str::of('{/var:1}'))->match( - static fn($expression) => $expression, - static fn() => null, - ), - Level4::of(Str::of('{var}'))->match( - static fn($expression) => $expression, - static fn() => null, - ), - ))->toString(), + Composite::of(Str::of('{/var:1,var}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), ); $this->assertSame( '{/list*,path:4}', - (new Composite( - '/', - Path::of(Str::of('{/list*}'))->match( - static fn($expression) => $expression, - static fn() => null, - ), - Level4::of(Str::of('{path:4}'))->match( - static fn($expression) => $expression, - static fn() => null, - ), - ))->toString(), + Composite::of(Str::of('{/list*,path:4}'))->match( + static fn($expression) => $expression->toString(), + static fn() => null, + ), ); } @@ -71,31 +57,17 @@ public function testExpand() $this->assertSame( '/v/value', - (new Composite( - '/', - Path::of(Str::of('{/var:1}'))->match( - static fn($expression) => $expression, - static fn() => null, - ), - Level4::of(Str::of('{var}'))->match( - static fn($expression) => $expression, - static fn() => null, - ), - ))->expand($variables), + Composite::of(Str::of('{/var:1,var}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); $this->assertSame( '/red/green/blue/%2Ffoo', - (new Composite( - '/', - Path::of(Str::of('{/list*}'))->match( - static fn($expression) => $expression, - static fn() => null, - ), - Level4::of(Str::of('{path:4}'))->match( - static fn($expression) => $expression, - static fn() => null, - ), - ))->expand($variables), + Composite::of(Str::of('{/list*,path:4}'))->match( + static fn($expression) => $expression->expand($variables), + static fn() => null, + ), ); } From 76fc73628af25c8e2899ba9a6a3aea928d806f8d Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sun, 31 Jul 2022 19:04:46 +0200 Subject: [PATCH 31/39] remove the use of state to build template regex --- src/Template.php | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/src/Template.php b/src/Template.php index e4964f1..d38aa99 100644 --- a/src/Template.php +++ b/src/Template.php @@ -117,40 +117,28 @@ public function toString(): string private function regex(): string { try { - $i = 0; - $j = 0; $template = $this ->expressions ->reduce( $this->template->replace('~', '\~'), - static function(Str $template, Expression $expression) use (&$i): Str { - /** - * @psalm-suppress MixedOperand - * @psalm-suppress MixedAssignment - */ - ++$i; - - return $template->replace( - $expression->toString(), - "__innmind_expression_{$i}__", - ); - }, + static fn(Str $template, $expression) => $template->replace( + $expression->toString(), + \sprintf( + '__innmind_expression_%s__', + \spl_object_hash($expression), + ), + ), ) ->pregQuote(); $template = $this->expressions->reduce( $template, - static function(Str $template, Expression $expression) use (&$j): Str { - /** - * @psalm-suppress MixedOperand - * @psalm-suppress MixedAssignment - */ - ++$j; - - return $template->replace( - "__innmind_expression_{$j}__", - $expression->regex(), - ); - }, + static fn(Str $template, $expression) => $template->replace( + \sprintf( + '__innmind_expression_%s__', + \spl_object_hash($expression), + ), + $expression->regex(), + ), ); } catch (LogicException $e) { throw new ExtractionNotSupported('', 0, $e); From 54d355b6270fd44723ab62fe74777ef53f0f57ef Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 6 Aug 2022 11:22:19 +0200 Subject: [PATCH 32/39] use more precise type for the Map of values to expand --- src/Expression.php | 2 +- src/Expression/Level1.php | 4 ++-- src/Expression/Level2/Fragment.php | 4 ++-- src/Expression/Level2/Reserved.php | 4 ++-- src/Expression/Level3.php | 1 + src/Expression/Level3/Fragment.php | 1 + src/Expression/Level3/Label.php | 1 + src/Expression/Level3/NamedValues.php | 1 + src/Expression/Level3/Path.php | 1 + src/Expression/Level3/Reserved.php | 1 + src/Expression/Level4.php | 11 +++++------ src/Expression/Level4/Parameters.php | 12 ++++-------- src/Expression/Level4/Query.php | 12 ++++-------- src/Expression/Level4/QueryContinuation.php | 12 ++++-------- src/Expression/Name.php | 12 ++++++++++++ src/Template.php | 2 +- 16 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/Expression.php b/src/Expression.php index c2aa01b..8ff7985 100644 --- a/src/Expression.php +++ b/src/Expression.php @@ -24,7 +24,7 @@ public static function of(Str $string): Maybe; public function expansion(): Expression\Expansion; /** - * @param Map $variables + * @param Map|list> $variables */ public function expand(Map $variables): string; public function regex(): string; diff --git a/src/Expression/Level1.php b/src/Expression/Level1.php index 764ddb2..23a8bf0 100644 --- a/src/Expression/Level1.php +++ b/src/Expression/Level1.php @@ -58,11 +58,11 @@ public function expand(Map $variables): string ->get($this->name->toString()) ->match( function($variable) { - if (\is_array($variable)) { + if (!\is_string($variable)) { throw new OnlyScalarCanBeExpandedForExpression($this->name->toString()); } - return ($this->encode)((string) $variable); + return ($this->encode)($variable); }, static fn() => '', ); diff --git a/src/Expression/Level2/Fragment.php b/src/Expression/Level2/Fragment.php index 09d3d3d..d9a0304 100644 --- a/src/Expression/Level2/Fragment.php +++ b/src/Expression/Level2/Fragment.php @@ -52,11 +52,11 @@ public function expand(Map $variables): string ->get($this->name->toString()) ->match( function($variable) { - if (\is_array($variable)) { + if (!\is_string($variable)) { throw new OnlyScalarCanBeExpandedForExpression($this->name->toString()); } - return '#'.($this->encode)((string) $variable); + return '#'.($this->encode)($variable); }, static fn() => '', ); diff --git a/src/Expression/Level2/Reserved.php b/src/Expression/Level2/Reserved.php index c57ab5a..94f37ef 100644 --- a/src/Expression/Level2/Reserved.php +++ b/src/Expression/Level2/Reserved.php @@ -60,11 +60,11 @@ public function expand(Map $variables): string ->get($this->name->toString()) ->match( function($variable) { - if (\is_array($variable)) { + if (!\is_string($variable)) { throw new OnlyScalarCanBeExpandedForExpression($this->name->toString()); } - return ($this->encode)((string) $variable); + return ($this->encode)($variable); }, static fn() => '', ); diff --git a/src/Expression/Level3.php b/src/Expression/Level3.php index f0295a1..350ea1c 100644 --- a/src/Expression/Level3.php +++ b/src/Expression/Level3.php @@ -67,6 +67,7 @@ public function regex(): string public function toString(): string { + /** @psalm-suppress InvalidArgument */ return Str::of(',') ->join($this->names->map( static fn($name) => $name->toString(), diff --git a/src/Expression/Level3/Fragment.php b/src/Expression/Level3/Fragment.php index d629e9a..4f720b2 100644 --- a/src/Expression/Level3/Fragment.php +++ b/src/Expression/Level3/Fragment.php @@ -76,6 +76,7 @@ public function regex(): string public function toString(): string { + /** @psalm-suppress InvalidArgument */ return Str::of(',') ->join($this->names->map( static fn($element) => $element->toString(), diff --git a/src/Expression/Level3/Label.php b/src/Expression/Level3/Label.php index b67af13..2effe4c 100644 --- a/src/Expression/Level3/Label.php +++ b/src/Expression/Level3/Label.php @@ -77,6 +77,7 @@ public function regex(): string public function toString(): string { + /** @psalm-suppress InvalidArgument */ return Str::of(',') ->join($this->names->map( static fn($element) => $element->toString(), diff --git a/src/Expression/Level3/NamedValues.php b/src/Expression/Level3/NamedValues.php index be87e8a..79c60d1 100644 --- a/src/Expression/Level3/NamedValues.php +++ b/src/Expression/Level3/NamedValues.php @@ -112,6 +112,7 @@ public function regex(): string public function toString(): string { + /** @psalm-suppress InvalidArgument */ return Str::of(',') ->join($this->names->map( static fn($element) => $element->toString(), diff --git a/src/Expression/Level3/Path.php b/src/Expression/Level3/Path.php index 20b1bdf..c4b815d 100644 --- a/src/Expression/Level3/Path.php +++ b/src/Expression/Level3/Path.php @@ -74,6 +74,7 @@ public function regex(): string public function toString(): string { + /** @psalm-suppress InvalidArgument */ return Str::of(',') ->join($this->names->map( static fn($element) => $element->toString(), diff --git a/src/Expression/Level3/Reserved.php b/src/Expression/Level3/Reserved.php index ad929ab..f9a401e 100644 --- a/src/Expression/Level3/Reserved.php +++ b/src/Expression/Level3/Reserved.php @@ -72,6 +72,7 @@ public function regex(): string public function toString(): string { + /** @psalm-suppress InvalidArgument */ return Str::of(',') ->join($this->names->map( static fn($element) => $element->toString(), diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index 3101ad8..dc94577 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -110,7 +110,6 @@ public function withExpression(callable $expression): self public function expand(Map $variables): string { - /** @var scalar|array{0:string, 1:scalar}|null */ $variable = $variables->get($this->name->toString())->match( static fn($variable) => $variable, static fn() => null, @@ -129,7 +128,7 @@ public function expand(Map $variables): string } if ($this->mustLimit()) { - $value = Str::of((string) $variable)->take($this->limit); + $value = Str::of($variable)->take($this->limit); $value = $this->expression->expand( ($variables)($this->name->toString(), $value->toString()), ); @@ -186,8 +185,8 @@ private function mustLimit(): bool /** * @no-named-arguments - * @param Map $variables - * @param array $variablesToExpand + * @param Map|list> $variables + * @param list|list $variablesToExpand */ private function expandList(Map $variables, ...$variablesToExpand): string { @@ -224,8 +223,8 @@ function($variableToExpand) use ($variables): string { } /** - * @param Map $variables - * @param array $variablesToExpand + * @param Map|list> $variables + * @param list|list $variablesToExpand */ private function explodeList(Map $variables, array $variablesToExpand): string { diff --git a/src/Expression/Level4/Parameters.php b/src/Expression/Level4/Parameters.php index d2df453..d16f636 100644 --- a/src/Expression/Level4/Parameters.php +++ b/src/Expression/Level4/Parameters.php @@ -80,12 +80,8 @@ public function expansion(): Expansion return Expansion::parameter; } - /** - * @param Map $variables - */ public function expand(Map $variables): string { - /** @var scalar|array{0:string, 1:scalar}|null */ $variable = $variables->get($this->name->toString())->match( static fn($variable) => $variable, static fn() => null, @@ -158,8 +154,8 @@ private function mustLimit(): bool /** * @no-named-arguments - * @param Map $variables - * @param array $variablesToExpand + * @param Map|list> $variables + * @param list|list $variablesToExpand */ private function expandList(Map $variables, ...$variablesToExpand): string { @@ -195,8 +191,8 @@ function($variableToExpand) use ($variables): string { } /** - * @param Map $variables - * @param array $variablesToExpand + * @param Map|list> $variables + * @param list|list $variablesToExpand */ private function explodeList(Map $variables, array $variablesToExpand): string { diff --git a/src/Expression/Level4/Query.php b/src/Expression/Level4/Query.php index 756e6b8..9394e9a 100644 --- a/src/Expression/Level4/Query.php +++ b/src/Expression/Level4/Query.php @@ -80,12 +80,8 @@ public function expansion(): Expansion return Expansion::query; } - /** - * @param Map $variables - */ public function expand(Map $variables): string { - /** @var scalar|array{0:string, 1:scalar}|null */ $variable = $variables->get($this->name->toString())->match( static fn($variable) => $variable, static fn() => null, @@ -158,8 +154,8 @@ private function mustLimit(): bool /** * @no-named-arguments - * @param Map $variables - * @param array $variablesToExpand + * @param Map|list> $variables + * @param list|list $variablesToExpand */ private function expandList(Map $variables, ...$variablesToExpand): string { @@ -194,8 +190,8 @@ static function($variableToExpand): Sequence { } /** - * @param Map $variables - * @param array $variablesToExpand + * @param Map|list> $variables + * @param list|list $variablesToExpand */ private function explodeList(Map $variables, array $variablesToExpand): string { diff --git a/src/Expression/Level4/QueryContinuation.php b/src/Expression/Level4/QueryContinuation.php index 83ed244..639bfe4 100644 --- a/src/Expression/Level4/QueryContinuation.php +++ b/src/Expression/Level4/QueryContinuation.php @@ -80,12 +80,8 @@ public function expansion(): Expansion return Expansion::queryContinuation; } - /** - * @param Map $variables - */ public function expand(Map $variables): string { - /** @var scalar|array{0:string, 1:scalar}|null */ $variable = $variables->get($this->name->toString())->match( static fn($variable) => $variable, static fn() => null, @@ -158,8 +154,8 @@ private function mustLimit(): bool /** * @no-named-arguments - * @param Map $variables - * @param array $variablesToExpand + * @param Map|list> $variables + * @param list|list $variablesToExpand */ private function expandList(Map $variables, ...$variablesToExpand): string { @@ -193,8 +189,8 @@ static function($variableToExpand): Sequence { } /** - * @param Map $variables - * @param array $variablesToExpand + * @param Map|list> $variables + * @param list|list $variablesToExpand */ private function explodeList(Map $variables, array $variablesToExpand): string { diff --git a/src/Expression/Name.php b/src/Expression/Name.php index dfba060..13f3a61 100644 --- a/src/Expression/Name.php +++ b/src/Expression/Name.php @@ -15,8 +15,12 @@ */ final class Name { + /** @var non-empty-string */ private string $value; + /** + * @param non-empty-string $value + */ private function __construct(string $value) { $this->value = $value; @@ -33,6 +37,7 @@ public static function of(string $value): self throw new DomainException($value); } + /** @psalm-suppress ArgumentTypeCoercion Because of the non-empty-string */ return new self($value); } @@ -45,6 +50,7 @@ public static function one( Str $value, Expansion $expansion, ): Maybe { + /** @psalm-suppress ArgumentTypeCoercion Because of the non-empty-string */ return Maybe::just($value) ->filter($expansion->matches(...)) ->map($expansion->clean(...)) @@ -61,6 +67,7 @@ public static function explode( Str $value, Expansion $expansion, ): Maybe { + /** @psalm-suppress ArgumentTypeCoercion Because of the non-empty-string */ return Maybe::just($value) ->filter($expansion->matchesExplode(...)) ->map($expansion->cleanExplode(...)) @@ -77,6 +84,7 @@ public static function limit( Str $value, Expansion $expansion, ): Maybe { + /** @psalm-suppress ArgumentTypeCoercion Because of the non-empty-string */ return Maybe::just($value) ->filter($expansion->matchesLimit(...)) ->map($expansion->clean(...)) @@ -106,6 +114,7 @@ public static function many( Str $value, Expansion $expansion, ): Maybe { + /** @psalm-suppress ArgumentTypeCoercion Because of the non-empty-string */ return Maybe::just($value) ->filter($expansion->matchesMany(...)) ->map($expansion->clean(...)) @@ -125,6 +134,9 @@ public static function characters(): string return '[a-zA-Z0-9_]+'; } + /** + * @return non-empty-string + */ public function toString(): string { return $this->value; diff --git a/src/Template.php b/src/Template.php index d38aa99..f894503 100644 --- a/src/Template.php +++ b/src/Template.php @@ -65,7 +65,7 @@ public static function maybe(string $template): Maybe } /** - * @param Map $variables + * @param Map|list> $variables */ public function expand(Map $variables): Url { From 4ce34874d99ac6557831e5ccab85aeead7f67036 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 6 Aug 2022 11:31:59 +0200 Subject: [PATCH 33/39] consider invalid types for expansions as non existing values --- .../OnlyScalarCanBeExpandedForExpression.php | 8 -------- src/Expression/Level1.php | 10 +++------- src/Expression/Level2/Fragment.php | 11 +++-------- src/Expression/Level2/Reserved.php | 11 +++-------- tests/Expression/Level1Test.php | 10 +++------- tests/Expression/Level2/FragmentTest.php | 10 +++------- tests/Expression/Level2/ReservedTest.php | 10 +++------- 7 files changed, 18 insertions(+), 52 deletions(-) delete mode 100644 src/Exception/OnlyScalarCanBeExpandedForExpression.php diff --git a/src/Exception/OnlyScalarCanBeExpandedForExpression.php b/src/Exception/OnlyScalarCanBeExpandedForExpression.php deleted file mode 100644 index 653db2e..0000000 --- a/src/Exception/OnlyScalarCanBeExpandedForExpression.php +++ /dev/null @@ -1,8 +0,0 @@ -get($this->name->toString()) + ->filter(\is_string(...)) ->match( - function($variable) { - if (!\is_string($variable)) { - throw new OnlyScalarCanBeExpandedForExpression($this->name->toString()); - } - - return ($this->encode)($variable); - }, + fn(string $variable) => ($this->encode)($variable), static fn() => '', ); } diff --git a/src/Expression/Level2/Fragment.php b/src/Expression/Level2/Fragment.php index d9a0304..f1d4e7b 100644 --- a/src/Expression/Level2/Fragment.php +++ b/src/Expression/Level2/Fragment.php @@ -8,7 +8,6 @@ Expression\Name, Expression\Expansion, UrlEncode, - Exception\OnlyScalarCanBeExpandedForExpression, }; use Innmind\Immutable\{ Map, @@ -48,16 +47,12 @@ public function expansion(): Expansion public function expand(Map $variables): string { + /** @psalm-suppress InvalidArgument Because of the filter */ return $variables ->get($this->name->toString()) + ->filter(\is_string(...)) ->match( - function($variable) { - if (!\is_string($variable)) { - throw new OnlyScalarCanBeExpandedForExpression($this->name->toString()); - } - - return '#'.($this->encode)($variable); - }, + fn(string $variable) => '#'.($this->encode)($variable), static fn() => '', ); } diff --git a/src/Expression/Level2/Reserved.php b/src/Expression/Level2/Reserved.php index 94f37ef..0cef2cf 100644 --- a/src/Expression/Level2/Reserved.php +++ b/src/Expression/Level2/Reserved.php @@ -8,7 +8,6 @@ Expression\Name, Expression\Expansion, UrlEncode, - Exception\OnlyScalarCanBeExpandedForExpression, }; use Innmind\Immutable\{ Map, @@ -56,16 +55,12 @@ public function expansion(): Expansion public function expand(Map $variables): string { + /** @psalm-suppress InvalidArgument Because of the filter */ return $variables ->get($this->name->toString()) + ->filter(\is_string(...)) ->match( - function($variable) { - if (!\is_string($variable)) { - throw new OnlyScalarCanBeExpandedForExpression($this->name->toString()); - } - - return ($this->encode)($variable); - }, + fn(string $variable) => ($this->encode)($variable), static fn() => '', ); } diff --git a/tests/Expression/Level1Test.php b/tests/Expression/Level1Test.php index 9c9d258..25cf00d 100644 --- a/tests/Expression/Level1Test.php +++ b/tests/Expression/Level1Test.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level1, Expression, - Exception\OnlyScalarCanBeExpandedForExpression, }; use Innmind\Immutable\{ Map, @@ -87,18 +86,15 @@ public function testRegex() ); } - public function testThrowWhenTryingToExpandWithAnArray() + public function testReturnEmptyStringWhenTryingToExpandWithAnArray() { $expression = Level1::of(Str::of('{foo}'))->match( static fn($expression) => $expression, static fn() => null, ); - $this->expectException(OnlyScalarCanBeExpandedForExpression::class); - $this->expectExceptionMessage('foo'); - - $expression->expand( + $this->assertSame('', $expression->expand( Map::of(['foo', ['value']]), - ); + )); } } diff --git a/tests/Expression/Level2/FragmentTest.php b/tests/Expression/Level2/FragmentTest.php index ec41157..cd89ebe 100644 --- a/tests/Expression/Level2/FragmentTest.php +++ b/tests/Expression/Level2/FragmentTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level2\Fragment, Expression, - Exception\OnlyScalarCanBeExpandedForExpression, }; use Innmind\Immutable\{ Map, @@ -90,18 +89,15 @@ public function testRegex() ); } - public function testThrowWhenTryingToExpandWithAnArray() + public function testReturnEmptyStringWhenTryingToExpandWithAnArray() { $expression = Fragment::of(Str::of('{#foo}'))->match( static fn($expression) => $expression, static fn() => null, ); - $this->expectException(OnlyScalarCanBeExpandedForExpression::class); - $this->expectExceptionMessage('foo'); - - $expression->expand( + $this->assertSame('', $expression->expand( Map::of(['foo', ['value']]), - ); + )); } } diff --git a/tests/Expression/Level2/ReservedTest.php b/tests/Expression/Level2/ReservedTest.php index 3094cb8..1b805f2 100644 --- a/tests/Expression/Level2/ReservedTest.php +++ b/tests/Expression/Level2/ReservedTest.php @@ -6,7 +6,6 @@ use Innmind\UrlTemplate\{ Expression\Level2\Reserved, Expression, - Exception\OnlyScalarCanBeExpandedForExpression, }; use Innmind\Immutable\{ Map, @@ -90,18 +89,15 @@ public function testRegex() ); } - public function testThrowWhenTryingToExpandWithAnArray() + public function testReturnEmptyStringWhenTryingToExpandWithAnArray() { $expression = Reserved::of(Str::of('{+foo}'))->match( static fn($expression) => $expression, static fn() => null, ); - $this->expectException(OnlyScalarCanBeExpandedForExpression::class); - $this->expectExceptionMessage('foo'); - - $expression->expand( + $this->assertSame('', $expression->expand( Map::of(['foo', ['value']]), - ); + )); } } From 8e69595deac1d0cbdfe06df745d81f5906f312a2 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 6 Aug 2022 11:38:36 +0200 Subject: [PATCH 34/39] remove the need to use variadics --- src/Expression/Level4.php | 6 ++---- src/Expression/Level4/Parameters.php | 8 +++----- src/Expression/Level4/Query.php | 8 +++----- src/Expression/Level4/QueryContinuation.php | 8 +++----- 4 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/Expression/Level4.php b/src/Expression/Level4.php index dc94577..f1dbf76 100644 --- a/src/Expression/Level4.php +++ b/src/Expression/Level4.php @@ -120,7 +120,7 @@ public function expand(Map $variables): string } if (\is_array($variable)) { - return $this->expandList($variables, ...$variable); + return $this->expandList($variables, $variable); } if ($this->explode) { @@ -184,11 +184,10 @@ private function mustLimit(): bool } /** - * @no-named-arguments * @param Map|list> $variables * @param list|list $variablesToExpand */ - private function expandList(Map $variables, ...$variablesToExpand): string + private function expandList(Map $variables, array $variablesToExpand): string { if ($this->explode) { return $this->explodeList($variables, $variablesToExpand); @@ -228,7 +227,6 @@ function($variableToExpand) use ($variables): string { */ private function explodeList(Map $variables, array $variablesToExpand): string { - /** @psalm-suppress NamedArgumentNotAllowed */ $expanded = Sequence::of(...$variablesToExpand)->map( function($variableToExpand) use ($variables): string { if (\is_array($variableToExpand)) { diff --git a/src/Expression/Level4/Parameters.php b/src/Expression/Level4/Parameters.php index d16f636..b4fcbba 100644 --- a/src/Expression/Level4/Parameters.php +++ b/src/Expression/Level4/Parameters.php @@ -92,11 +92,11 @@ public function expand(Map $variables): string } if (\is_array($variable)) { - return $this->expandList($variables, ...$variable); + return $this->expandList($variables, $variable); } if ($this->explode) { - return $this->expandList($variables, $variable); + return $this->explodeList($variables, [$variable]); } $value = Str::of($this->expression->expand($variables)); @@ -153,11 +153,10 @@ private function mustLimit(): bool } /** - * @no-named-arguments * @param Map|list> $variables * @param list|list $variablesToExpand */ - private function expandList(Map $variables, ...$variablesToExpand): string + private function expandList(Map $variables, array $variablesToExpand): string { if ($this->explode) { return $this->explodeList($variables, $variablesToExpand); @@ -196,7 +195,6 @@ function($variableToExpand) use ($variables): string { */ private function explodeList(Map $variables, array $variablesToExpand): string { - /** @psalm-suppress NamedArgumentNotAllowed */ $expanded = Sequence::of(...$variablesToExpand)->map( function($variableToExpand) use ($variables): string { $name = $this->name; diff --git a/src/Expression/Level4/Query.php b/src/Expression/Level4/Query.php index 9394e9a..275579a 100644 --- a/src/Expression/Level4/Query.php +++ b/src/Expression/Level4/Query.php @@ -92,11 +92,11 @@ public function expand(Map $variables): string } if (\is_array($variable)) { - return $this->expandList($variables, ...$variable); + return $this->expandList($variables, $variable); } if ($this->explode) { - return $this->expandList($variables, $variable); + return $this->explodeList($variables, [$variable]); } $value = Str::of($this->expression->expand($variables)); @@ -153,11 +153,10 @@ private function mustLimit(): bool } /** - * @no-named-arguments * @param Map|list> $variables * @param list|list $variablesToExpand */ - private function expandList(Map $variables, ...$variablesToExpand): string + private function expandList(Map $variables, array $variablesToExpand): string { if ($this->explode) { return $this->explodeList($variables, $variablesToExpand); @@ -195,7 +194,6 @@ static function($variableToExpand): Sequence { */ private function explodeList(Map $variables, array $variablesToExpand): string { - /** @psalm-suppress NamedArgumentNotAllowed */ $expanded = Sequence::of(...$variablesToExpand)->map(function($variableToExpand) use ($variables): string { $name = $this->name; diff --git a/src/Expression/Level4/QueryContinuation.php b/src/Expression/Level4/QueryContinuation.php index 639bfe4..c73fb12 100644 --- a/src/Expression/Level4/QueryContinuation.php +++ b/src/Expression/Level4/QueryContinuation.php @@ -92,11 +92,11 @@ public function expand(Map $variables): string } if (\is_array($variable)) { - return $this->expandList($variables, ...$variable); + return $this->expandList($variables, $variable); } if ($this->explode) { - return $this->expandList($variables, $variable); + return $this->explodeList($variables, [$variable]); } $value = Str::of($this->expression->expand($variables)); @@ -153,11 +153,10 @@ private function mustLimit(): bool } /** - * @no-named-arguments * @param Map|list> $variables * @param list|list $variablesToExpand */ - private function expandList(Map $variables, ...$variablesToExpand): string + private function expandList(Map $variables, array $variablesToExpand): string { if ($this->explode) { return $this->explodeList($variables, $variablesToExpand); @@ -194,7 +193,6 @@ static function($variableToExpand): Sequence { */ private function explodeList(Map $variables, array $variablesToExpand): string { - /** @psalm-suppress NamedArgumentNotAllowed */ $expanded = Sequence::of(...$variablesToExpand)->map(function($variableToExpand) use ($variables): string { $name = $this->name; From f9ebb7bb9774919271153d7afe8f06df6e0b9176 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 6 Aug 2022 11:42:12 +0200 Subject: [PATCH 35/39] return an empty map instead of throwing when the url does not match the template --- src/Exception/RuntimeException.php | 8 -------- src/Exception/UrlDoesntMatchTemplate.php | 8 -------- src/Template.php | 5 ----- tests/TemplateTest.php | 11 +++++------ 4 files changed, 5 insertions(+), 27 deletions(-) delete mode 100644 src/Exception/RuntimeException.php delete mode 100644 src/Exception/UrlDoesntMatchTemplate.php diff --git a/src/Exception/RuntimeException.php b/src/Exception/RuntimeException.php deleted file mode 100644 index 861ab6e..0000000 --- a/src/Exception/RuntimeException.php +++ /dev/null @@ -1,8 +0,0 @@ -regex(); $url = Str::of($url->toString()); - if (!$url->matches($regex)) { - throw new UrlDoesntMatchTemplate($url->toString()); - } - /** @var Map */ return $url ->capture($regex) diff --git a/tests/TemplateTest.php b/tests/TemplateTest.php index 35959c3..36bf79e 100644 --- a/tests/TemplateTest.php +++ b/tests/TemplateTest.php @@ -5,7 +5,6 @@ use Innmind\UrlTemplate\{ Template, - Exception\UrlDoesntMatchTemplate, Exception\ExtractionNotSupported, }; use Innmind\Url\Url; @@ -58,12 +57,12 @@ public function testExpand($pattern, $expected) $this->assertSame($expected, $url->toString()); } - public function testThrowWhenUrlDoesntMatchTemplate() + public function testReturnEmptyMapWhenUrlDoesntMatchTemplate() { - $this->expectException(UrlDoesntMatchTemplate::class); - $this->expectExceptionMessage('/hello%20world%21/foo'); - - Template::of('/{foo}')->extract(Url::of('/hello%20world%21/foo')); + $this->assertCount( + 0, + Template::of('/{foo}')->extract(Url::of('/hello%20world%21/foo')), + ); } public function testLevel1Extraction() From 4bf0ae4e28bc53a90854d1384e660a013f8406c3 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 6 Aug 2022 11:48:12 +0200 Subject: [PATCH 36/39] remove wrapping the exception explaining why the match is not possible --- src/Exception/ExtractionNotSupported.php | 8 ---- src/Template.php | 49 +++++++++++++----------- tests/TemplateTest.php | 4 +- 3 files changed, 28 insertions(+), 33 deletions(-) delete mode 100644 src/Exception/ExtractionNotSupported.php diff --git a/src/Exception/ExtractionNotSupported.php b/src/Exception/ExtractionNotSupported.php deleted file mode 100644 index 8e66667..0000000 --- a/src/Exception/ExtractionNotSupported.php +++ /dev/null @@ -1,8 +0,0 @@ - */ public function extract(Url $url): Map @@ -96,6 +97,9 @@ public function extract(Url $url): Map ->map(static fn($_, $variable) => \rawurldecode($variable->toString())); } + /** + * @throws ExplodeExpressionCantBeMatched + */ public function matches(Url $url): bool { $regex = $this->regex(); @@ -109,35 +113,34 @@ public function toString(): string return $this->template->toString(); } + /** + * @throws ExplodeExpressionCantBeMatched + */ private function regex(): string { - try { - $template = $this - ->expressions - ->reduce( - $this->template->replace('~', '\~'), - static fn(Str $template, $expression) => $template->replace( - $expression->toString(), - \sprintf( - '__innmind_expression_%s__', - \spl_object_hash($expression), - ), - ), - ) - ->pregQuote(); - $template = $this->expressions->reduce( - $template, + $template = $this + ->expressions + ->reduce( + $this->template->replace('~', '\~'), static fn(Str $template, $expression) => $template->replace( + $expression->toString(), \sprintf( '__innmind_expression_%s__', \spl_object_hash($expression), ), - $expression->regex(), ), - ); - } catch (LogicException $e) { - throw new ExtractionNotSupported('', 0, $e); - } + ) + ->pregQuote(); + $template = $this->expressions->reduce( + $template, + static fn(Str $template, $expression) => $template->replace( + \sprintf( + '__innmind_expression_%s__', + \spl_object_hash($expression), + ), + $expression->regex(), + ), + ); return $template->prepend('~^')->append('$~')->toString(); } diff --git a/tests/TemplateTest.php b/tests/TemplateTest.php index 36bf79e..c70004b 100644 --- a/tests/TemplateTest.php +++ b/tests/TemplateTest.php @@ -5,7 +5,7 @@ use Innmind\UrlTemplate\{ Template, - Exception\ExtractionNotSupported, + Exception\ExplodeExpressionCantBeMatched, }; use Innmind\Url\Url; use Innmind\Immutable\{ @@ -401,7 +401,7 @@ public function testExtraction() public function testThrowWhenExtractionNotSupportedForTemplate() { - $this->expectException(ExtractionNotSupported::class); + $this->expectException(ExplodeExpressionCantBeMatched::class); Template::of('{foo*}')->extract(Url::of('foo,bar,baz')); } From 48d6bf4c61a0486d9883daf50e5a2d71ba5eba20 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 6 Aug 2022 11:50:24 +0200 Subject: [PATCH 37/39] only expose the Template class to the users --- src/Expression.php | 1 + src/Expression/Expansion.php | 1 + src/Expression/Name.php | 1 + src/Expressions.php | 1 + src/UrlEncode.php | 1 + 5 files changed, 5 insertions(+) diff --git a/src/Expression.php b/src/Expression.php index 8ff7985..240084b 100644 --- a/src/Expression.php +++ b/src/Expression.php @@ -11,6 +11,7 @@ /** * @psalm-immutable + * @internal */ interface Expression { diff --git a/src/Expression/Expansion.php b/src/Expression/Expansion.php index 8d4c812..310cc2f 100644 --- a/src/Expression/Expansion.php +++ b/src/Expression/Expansion.php @@ -7,6 +7,7 @@ /** * @psalm-immutable + * @internal */ enum Expansion { diff --git a/src/Expression/Name.php b/src/Expression/Name.php index 13f3a61..289dda4 100644 --- a/src/Expression/Name.php +++ b/src/Expression/Name.php @@ -12,6 +12,7 @@ /** * @psalm-immutable + * @internal */ final class Name { diff --git a/src/Expressions.php b/src/Expressions.php index 452baac..59c186f 100644 --- a/src/Expressions.php +++ b/src/Expressions.php @@ -11,6 +11,7 @@ /** * @psalm-immutable + * @internal */ final class Expressions { diff --git a/src/UrlEncode.php b/src/UrlEncode.php index 8f7944d..3ed78f7 100644 --- a/src/UrlEncode.php +++ b/src/UrlEncode.php @@ -11,6 +11,7 @@ /** * @psalm-immutable + * @internal */ final class UrlEncode { From 111a362f030eabe7a99bf8c48a4ae744621f1b64 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 6 Aug 2022 11:52:08 +0200 Subject: [PATCH 38/39] fix readme --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index bf10adc..478da25 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,7 @@ use Innmind\Immutable\Map; use Innmind\Url\Url; $url = Template::of('http://example.com/dictionary/{term:1}/{term}')->expand( - Map::of('string', 'scalar|array') - ('term', 'dog') + Map::of(['term', 'dog']), ); $url instanceof Url; // true $url->toString(); // http://example.com/dictionary/d/dog From c040185414df2ef88769e4728d616bc8f25d796b Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 6 Aug 2022 11:52:58 +0200 Subject: [PATCH 39/39] CS --- src/Template.php | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Template.php b/src/Template.php index 94c6cf4..4bbe08f 100644 --- a/src/Template.php +++ b/src/Template.php @@ -87,12 +87,9 @@ static function(Str $template, Expression $expression) use ($variables): Str { */ public function extract(Url $url): Map { - $regex = $this->regex(); - $url = Str::of($url->toString()); - /** @var Map */ - return $url - ->capture($regex) + return Str::of($url->toString()) + ->capture($this->regex()) ->filter(static fn($key) => \is_string($key)) ->map(static fn($_, $variable) => \rawurldecode($variable->toString())); } @@ -102,10 +99,7 @@ public function extract(Url $url): Map */ public function matches(Url $url): bool { - $regex = $this->regex(); - $url = Str::of($url->toString()); - - return $url->matches($regex); + return Str::of($url->toString())->matches($this->regex()); } public function toString(): string