The problem here is somehow bringing the serializer through the object-safe API (of ObjectSafeRound) so that the user could call it in the methods of Round responsible for handling messages.
What we want is for the user to provide two methods
and pass those methods to methods of Round somehow.
It is possible to do with serialize, via erased-serde: in Round::make_direct_message() we wrap some Message: Serialize into Box<dyn erased_serde::Serialize> and pass to the session level, which can apply the user-provided serialize to it. But it seems to be impossible to do with deserialize, unless the user can instead provide an object implementing serde::Deserializer, which can then be wrapped in Box<dyn erased_serde::Deserializer> and passed to Round::receive_message. Unfortunately, most popular libraries do not expose such an object (a rare example of a library that does is serde_json).
This PR instead introduces a S: Serializer generic parameter to Round, which makes it possible to do (de)serialization statically. The downside is a more complicated API for both protocol writers and protocol users.
Alternatively, we could go the Box<dyn erased_serde::Deserializer> way, make a PR to the libraries we plan to use exposing the Deserializer, and let users who want other formats deal with format implementors themselves. I think I will prepare an alternative PR exploring this possibility and see how it looks.
Fixes #26
The problem here is somehow bringing the serializer through the object-safe API (of
ObjectSafeRound
) so that the user could call it in the methods ofRound
responsible for handling messages.What we want is for the user to provide two methods
and pass those methods to methods of
Round
somehow.It is possible to do with
serialize
, viaerased-serde
: inRound::make_direct_message()
we wrap someMessage: Serialize
intoBox<dyn erased_serde::Serialize>
and pass to the session level, which can apply the user-providedserialize
to it. But it seems to be impossible to do withdeserialize
, unless the user can instead provide an object implementingserde::Deserializer
, which can then be wrapped inBox<dyn erased_serde::Deserializer>
and passed toRound::receive_message
. Unfortunately, most popular libraries do not expose such an object (a rare example of a library that does isserde_json
).This PR instead introduces a
S: Serializer
generic parameter toRound
, which makes it possible to do (de)serialization statically. The downside is a more complicated API for both protocol writers and protocol users.Alternatively, we could go the
Box<dyn erased_serde::Deserializer>
way, make a PR to the libraries we plan to use exposing theDeserializer
, and let users who want other formats deal with format implementors themselves. I think I will prepare an alternative PR exploring this possibility and see how it looks.