Skip to content

Support traits that can't implement erased_serde::Serialize directly #113

@ibraheemdev

Description

@ibraheemdev

I have types that erased_serde::Serialize directly because they require extra arguments for context, so instead they have a custom serialize method. Unfortunately, this prevents me from using erased_serde::serialize, because the erased_serde::Serialize is sealed. Here's what I would like to work:

trait Object {
    fn erased_serialize(
        &self,
        extra: &str,
        serializer: &dyn erased_serde::Serializer,
    ) -> Result<(), erased_serde::Error>;

    // fn do_erased_serialize...
}

struct Manager {
    extra: String,
    object: Box<dyn Object>,
}

impl serde::Serialize for Manager {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        struct SerializeObjectWithExtra<'a>(&'a dyn Object, &'a str);

        // This part is not supported currently.
        impl erased_serde::SerializeBecause for SerializeObjectWithExtra<'_> {
            fn erased_serialize(
                &self,
                serializer: &mut dyn erased_serde::Serializer,
            ) -> Result<(), erased_serde::Error> {
                self.0.serialize(self.1, serializer)
            }

            // fn do_erased_serialize...
        }

        erased_serde::serialize(
            &SerializeObjectWithExtra(&*self.object, &self.extra),
            serializer,
        )
    }
}

The way I am hacking around this currently is instead defining Object as:

trait Object {
    fn as_serialize<'a>(&'a self, extra: &'a str) -> Box<dyn erased_serde::Serialize + 'a>;
}

But this requires an extra allocation that I would like to avoid.

I'm not sure if unsealing erased_serde::Serialize is the best way to support this, because as I understand it, erased_serde needs access to a concrete serde::Serialize at some point to create the erased type, and you probably don't want to expose do_erased_serialize publicly. Is there a better way to do this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions