Object safety for TryFrom somehow?


#1

So, for my library I have an idea about a automatic conversion from the plain HttpRequest into an extended version, where extended version type will be defined by user in the http handler function.

For example, if user is creating an Json RPC application, he can define a JsonRpcRequest, which will extend the basic HttpRequest and provide automatic data validation and parsing, so in result it will just need to create a function fn list_users(req: JsonRpcRequest) and my library will try to convert it’s own HttpRequest into JsonRpcRequest, and if conversion was okay, it will pass it into function.

With help from #rust-beginners (which was amazing, btw!) I’d resulted with a code similar to following, which is processing conversion and handler call.

fn call<F, R, T>(func: F, req: R) -> Result<(), <T as TryFrom<R>>::Err>
        where F: Fn(&T), R: Request, T: TryFrom<R> {
    let extended_req = T::try_from(req)?;
    (func)(&extended_req);
    Ok(())
}

Right now my main problem is that I can’t create a URL router, which will store all those user handlers, because each handler signature is Fn(TryFrom<Request>), but TryFrom is using Self, so it is not object-safe and can’t be stored as a trait object like this:

struct Router {
    urls: Vec<Box<Fn(&TryFrom<Request, Err=ConvertError>)>>
}

So, is there any way to bypass that restriction and store handlers in vector?

Truncated code example:

Playground link also.