SPA Pod (de)serialization
This adds a serde
-like framework for SPA pod serialization and deserialization.
The PodSerialize
, PodDeserialize
and FixedSizedPod
traits (the last one needed for Array
pods) let any type be used in/as pods, as long as it implements the relevant trait.
Right now, this only deals with a subset of possible pods. All other types should not be too hard to add, but will require some more design on how the rust representation should look, and this MR is already big enough.
This MR replaces the abandoned !2 (closed) with a different approach, but also uses some parts of that MR, so thanks to the original author.
I tried a number of designs (purely trait based where each implementor simply serializes itself, one big enum of all pod variants), but the serde
-like design is both the hardest-to-misuse and easiest-to-use of them all.
There are some details that I would like some review on specifically:
-
The typestate pattern in the
PodSerializer
/PodDeserializer
structs: APodSerialize
/PodDeserialize
implementor calls e.g.serialize_struct()
on the serializer, which makes the original
&mut PodSerializer
unusable until theStructPodSerializer
is finished by calling itsend()
method.
An implementor could forget to callend()
and simply return orstd::mem::drop()
theStructPodSerializer
, which would result in an invalid struct being serialized.
Unfortunately, I didn't find a good way to protect against this.Can we accept the API not being impossible-to-misuse like this?
-
The
StructPodDeserializer
returns aResult<Option<P>, ..>
to indicate with aNone
when no more fields are left. This is pretty unergonomic for implementors (?
on the result and then having tounwrap()
the option anyways), but I didn't find a better way either.
Edit: For convenience, I would also add a derive-macro for automatic (de)serialization of structs into Struct
pods in a later MR, as that is the only kind of pod (right not at least) that we cannot provide an implementation for.