A problem that I now have for the second time is how to work with some trait both in a dynamic way (i.e. with trait objects) as well as being able to serialize/deserialize the "trait objects", aaand the trait also has an associated type.
Here is the concrete setup. I'm building some sort of server, and I want to build an abstraction for a Request+Response pair. The idea is the user should basically provide three things:
- n "request types"
- n "response types"
- n
handle()
functions where the i'th handle function takes an object of request type i and spits out an object of reponse type i
From that data, I then provide basically some sort of server which handles everything, by deserializing an incoming request into the respective request type, calling the respective handle
, and serializing the obtained response type and send the response.
I model this as follows:
trait Request {
type Response;
fn handle(self) -> Self::Response;
}
Then the user should implement Request
on a bunch of types, let's call them ReqA
, ReqB
, ReqC
, and also implement Serialize
+Deserialize
on those types and on the associated Response types. (I didn't put trait bounds for simplicity.)
Now one could imagine that I would create some enum with all the request types:
enum Req {
A(ReqA),
B(ReqB),
C(ReqC),
}
Then my server should look roughly like this (pseudocode):
let request_binary = get_from_socket();
let request: Req = bincode::deserialize(request_binary);
let response = request.handle() // doesn't work, can't call function on enum variant,
// and type of `response` is not clear
let response_binary = bincode::serialize(response);
send_to_socket(response);
Now there are two problems:
-
I don't know how to handle the abstraction of calling
handle
. One might think that one could implementRequest
for theenum Req
, but that doesn't work because the return type ofhandle
is different for each request. So I definitely need to do some trait object stuff I guess. -
But as soon as I do trait objects, I have a problem with serialization/deserialization. It somehow still needs to serialize/deserialize a
Request
as if it was an enum variant.(Not so with the response, because the client will know the type it expects to get responded, so it can directly (try to) deserialize into the respective response type.)
For the second problem I found typetag which also lists a quite similar example. However, it doesn't support associated types.
So I was wondering if you guys have any ideas. Maybe I could do something similar like typetag but customized for my own problem?