dtolnay / erased-serde

Type-erased Serialize, Serializer and Deserializer traits
Apache License 2.0
709 stars 36 forks source link

Example of using with serde macros #20

Closed marcelbuesing closed 6 years ago

marcelbuesing commented 6 years ago

I'm trying to do the same as in issue #5 just with the current version of the crate.

#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_json;
extern crate erased_serde;

trait Element: erased_serde::Serialize + Send + Sync {
    /* ... */
}

impl serde::Serialize for Element {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: serde::Serializer
    {
        self.erased_serialize(serializer).map_err(|err| {
            serde::ser::Error::custom(err.to_string())
        })
    }
}

But I assume due to changes in serde::Serialize I now run into:

error[E0053]: method `serialize` has an incompatible type for trait
   |
13 | /     fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
14 | |         where S: serde::Serializer
15 | |     {
16 | |         self.erased_serialize(serializer).map_err(|err| {
17 | |             serde::ser::Error::custom(err.to_string())
18 | |         })
19 | |     }
   | |_____^ expected type parameter, found &mut S

I managed to get this far, but I am unable get passed the associated type problem. Do you possibly have any idea how to make this work?

#[macro_use]
extern crate serde_derive;

extern crate erased_serde;
extern crate serde;
extern crate serde_json;

trait Element: erased_serde::Serialize + Send + Sync {
    /* ... */
}

impl serde::Serialize for Element {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        self.erased_serialize(&mut erased_serde::Serializer::erase(serializer))
    }
}
   |
13 |       fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
   |                                                ----------------------- expected `std::result::Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>` because of return type
...
18 | /         self.erased_serialize(&mut erased_serde::Serializer::erase(serializer))
19 | |             .and_then(|x| Ok(()))
   | |_________________________________^ expected associated type, found ()
   |
   = note: expected type `std::result::Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>`
              found type `std::result::Result<(), erased_serde::Error>`

error: aborting due to previous error
dtolnay commented 6 years ago

This page shows how to serialize trait objects: https://docs.rs/erased-serde/0.3/erased_serde/macro.serialize_trait_object.html.

marcelbuesing commented 6 years ago

Awesome! Thank you so much for the super fast response. I missed that part in the documentation.