entropyxyz / manul

Round-based distributed protocols
https://docs.rs/manul
GNU Affero General Public License v3.0
1 stars 1 forks source link

Make supplying a serializer the user's responsibility #33

Open fjarri opened 4 hours ago

fjarri commented 4 hours ago

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 of Round responsible for handling messages.

What we want is for the user to provide two methods

fn serialize<T: Serialize>(value: T) -> Result<Box<[u8]>, LocalError>;
fn deserialize<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result<T, DeserializationError>;

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.

fjarri commented 4 hours ago

@dvdplm This PR is kind of experimental, so I would like to know your opinion on