From b1cf3a4c0aaa7423e8c5f2a391d28e7e83756b7f Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 6 Sep 2025 16:21:47 +0200 Subject: [PATCH 1/2] add handle proxy --- CHANGELOG.md | 1 + proofs/router.php | 40 +++++++++++++++++++++++++++++ src/Handle.php | 8 ++++-- src/Handle/Proxy.php | 39 ++++++++++++++++++++++++++++ src/Pipe/Endpoint/Method/Spread.php | 4 +-- src/Pipe/Forward/Method/Spread.php | 4 +-- src/Pipe/Method/Endpoint/Spread.php | 4 +-- 7 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 src/Handle/Proxy.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 66305bb..1393b91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added - `Pipe->endpoint()->{method}()` pattern +- `Innmind\Router\Handle\Proxy` ### Fixed diff --git a/proofs/router.php b/proofs/router.php index f3af72f..6ccde92 100644 --- a/proofs/router.php +++ b/proofs/router.php @@ -638,4 +638,44 @@ static function($assert, $url, $method, $other, $protocolVersion) { ); }, ); + + yield proof( + 'Handle::of() with a proxy', + given( + Set::of(...Http\Method::cases()), + Set::of(...Http\ProtocolVersion::cases()), + Set::of(...Http\Response\StatusCode::cases()), + ), + static function($assert, $method, $protocolVersion, $status) { + $req = Http\ServerRequest::of( + Url::of('/foo'), + $method, + $protocolVersion, + ); + $expected = Http\Response::of( + $status, + $req->protocolVersion(), + ); + $router = Router::of( + Method::{$method->name}() + ->map(Collect::of('method2')) + ->pipe(Collect::merge(Endpoint::of('{/name}'))) + ->pipe(Handle::of(Handle\Proxy::of( + static fn() => static function($method2, $name, $request, $unknown = null) use ($req, $expected, $assert, $method) { + $assert->same($method, $method2); + $assert->same('foo', $name); + $assert->same($req, $request); + $assert->null($unknown); + + return Attempt::result($expected); + }, + ))), + ); + + $assert->same( + $expected, + $router($req)->unwrap(), + ); + }, + ); }; diff --git a/src/Handle.php b/src/Handle.php index 609edf0..2cca4b5 100644 --- a/src/Handle.php +++ b/src/Handle.php @@ -33,16 +33,20 @@ public static function via(callable $handler): Component /** * @psalm-pure * - * @param callable(...mixed): Attempt $handler + * @param Handle\Proxy|(callable(mixed...): Attempt) $handler * * @return Component, Response> */ #[\NoDiscard] - public static function of(callable $handler): Component + public static function of(Handle\Proxy|callable $handler): Component { /** @var Component, Response> */ return self::via( static function($request, Map $variables) use ($handler) { + if ($handler instanceof Handle\Proxy) { + $handler = $handler->unwrap(); + } + if (!$variables->contains('request')) { $variables = ($variables)('request', $request); } diff --git a/src/Handle/Proxy.php b/src/Handle/Proxy.php new file mode 100644 index 0000000..b582c28 --- /dev/null +++ b/src/Handle/Proxy.php @@ -0,0 +1,39 @@ +) $load + */ + private function __construct( + private \Closure $load, + ) { + } + + public function __invoke(mixed ...$args): Attempt + { + return ($this->load)()(...$args); + } + + /** + * @param callable(): (callable(mixed...): Attempt) $load + */ + public static function of(callable $load): self + { + return new self(\Closure::fromCallable($load)); + } + + /** + * @return callable(...mixed): Attempt + */ + public function unwrap(): callable + { + return ($this->load)(); + } +} diff --git a/src/Pipe/Endpoint/Method/Spread.php b/src/Pipe/Endpoint/Method/Spread.php index d40b026..419ab60 100644 --- a/src/Pipe/Endpoint/Method/Spread.php +++ b/src/Pipe/Endpoint/Method/Spread.php @@ -39,12 +39,12 @@ public static function of(Component $previous): self } /** - * @param callable(...mixed): Attempt $handle + * @param Handle\Proxy|(callable(mixed...): Attempt) $handle * * @return Component */ #[\NoDiscard] - public function handle(callable $handle): Component + public function handle(Handle\Proxy|callable $handle): Component { /** @psalm-suppress MixedArgumentTypeCoercion */ return $this->previous->feed(Handle::of($handle)); diff --git a/src/Pipe/Forward/Method/Spread.php b/src/Pipe/Forward/Method/Spread.php index 10665fb..aa318ea 100644 --- a/src/Pipe/Forward/Method/Spread.php +++ b/src/Pipe/Forward/Method/Spread.php @@ -39,12 +39,12 @@ public static function of(Component $previous): self } /** - * @param callable(...mixed): Attempt $handle + * @param Handle\Proxy|(callable(mixed...): Attempt) $handle * * @return Component, Http\Response> */ #[\NoDiscard] - public function handle(callable $handle): Component + public function handle(Handle\Proxy|callable $handle): Component { /** @psalm-suppress MixedArgumentTypeCoercion */ return $this->previous->feed(Handle::of($handle)); diff --git a/src/Pipe/Method/Endpoint/Spread.php b/src/Pipe/Method/Endpoint/Spread.php index b7d5d1f..812ea69 100644 --- a/src/Pipe/Method/Endpoint/Spread.php +++ b/src/Pipe/Method/Endpoint/Spread.php @@ -46,12 +46,12 @@ public static function of( } /** - * @param callable(...mixed): Attempt $handle + * @param Handle\Proxy|(callable(mixed...): Attempt) $handle * * @return Component */ #[\NoDiscard] - public function handle(callable $handle): Component + public function handle(Handle\Proxy|callable $handle): Component { /** @psalm-suppress MixedArgumentTypeCoercion Don't know why it complains */ return $this From 33882fe519fcfba5adb9df10ef0771a31fb05427 Mon Sep 17 00:00:00 2001 From: Baptiste Langlade Date: Sat, 6 Sep 2025 16:23:03 +0200 Subject: [PATCH 2/2] remove unreachable code --- src/Handle/Proxy.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Handle/Proxy.php b/src/Handle/Proxy.php index b582c28..408fce3 100644 --- a/src/Handle/Proxy.php +++ b/src/Handle/Proxy.php @@ -16,11 +16,6 @@ private function __construct( ) { } - public function __invoke(mixed ...$args): Attempt - { - return ($this->load)()(...$args); - } - /** * @param callable(): (callable(mixed...): Attempt) $load */