I am trying out Rust and ❤️ it so far.
But currently I am stuck with generic traits :)
Status Quo:
There is this trait I want to implement, which I cannot modify:
pub trait Handler<R, B, E> {
fn run(&mut self, event: http::Request<B>) -> Result<R, E>;
}
One implementation of that trait in the same library is:
impl<Function, R, B, E> Handler<R, B, E> for Function
where
Function: FnMut(http::Request<B>) -> Result<R, E>,
{
fn run(&mut self, event: http::Request<B>) -> Result<R, E> {
(*self)(event)
}
}
And this implementation can be used as follows:
fn handler(req: http::Request<Body>) -> Result<impl IntoResponse, MyError> {
...
}
With the IntoReponse
trait:
pub trait IntoResponse {
fn into_response(self) -> Response<Body>;
}
What I want to do:
I want to implement that trait for a struct to be able to be used with the types mentioned above.
I tried:
impl Handler<impl IntoResponse, Body, MyError> for GQLHandler {
fn run(&mut self, req: http::Request<Body>) -> Result<impl IntoResponse, MyError> {
...
}
}
But that results in the errors:
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
--> handlers/gql.rs:18:14
|
18 | impl Handler<impl IntoResponse, Body, NowError> for GQLHandler {
| ^^^^^^^^^^^^^^^^^
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
--> handlers/gql.rs:19:59
|
19 | fn run(&mut self, req: http::Request<Body>) -> Result<impl IntoResponse, NowError> {
| ^^^^^^^^^^^^^^^^^
It works of cause if I implement it for a specific type, e.g.
impl Handler<http::Response<Body>, Body, NowError> for GQLHandler {
fn run(&mut self, req: http::Request<Body>) -> Result<http::Response<Body>, NowError> {
but I would like to keep the impl Trait
somehow.
Looking forward to any suggestions.
Thanks & Cheers Thomas
EDIT:
Following up on @MaxV's answer (Thanks!), sadly that did not work for me (which is why I did not accept this answer yet).
When trying to return Ok(...)
with a type implementing IntoResponse
, I get the following error:
|
3 | impl<T: IntoResponse> Handler<T, Body, MyError> for GQLHandler {
| - this type parameter
4 | fn run(&mut self, req: Request<Body>) -> Result<T, MyError> {
5 | Ok(Response::<()>::new(()))
| ^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found struct `http::Response`
|
= note: expected type parameter `T`
found struct `http::Response<()>`
even though I implemented IntoResponse
for Response
:
trait IntoResponse{
fn foo(&self);
}
impl IntoResponse for Response<()>
{
fn foo(&self) {}
}
What am I missing?