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..408fce3 --- /dev/null +++ b/src/Handle/Proxy.php @@ -0,0 +1,34 @@ +) $load + */ + private function __construct( + private \Closure $load, + ) { + } + + /** + * @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