How to implement "dynamic" serialization with serde

First of all some context: I am using an ECS system (shipyard) and I want to serialize a subset of entities using serde. This more or less ends up to get a list of components for every entity and serialize them using a custom map. I have complete control over the components so it is quite straightforward to just write the same 5 lines of code for every component but this is... inelegant? g

I'd better like to keep a registry of "serializers", each with an associated function that given the entity and some other parameters return a key and a serializable object that represents the component. Something like:

fn get_component<T: Serialize>(world: &World, entity_id: EntityId) -> (String, T);

with that the entity serialization becomes something like:

let mut m = serializer.serialize_map(None)?;
for s in serializers.iter() {
    let (k, c) = s.get_component(world, entity_id);
    m.serialize_entry(&k, &c)?;

Only problem, I cannot just loop over the serializers, because I need a concrete type to call get_component.

Any idea about to correctly this in Rust using Serde?

You may be interested in erased_serde which allows you to use serde with trait objects

1 Like