dtolnay / erased-serde

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

Allow the erased `Serialize` trait to report the type name #63

Closed cfrantz closed 1 year ago

cfrantz commented 2 years ago

After https://github.com/dtolnay/serde-yaml/pull/234, I decided to write my own serde serializer/deserializer to accomplish what I wanted regarding text serialization with comments, blocks and alternate integer bases. Serde-annotate allows one to emit such documents in a variety of formats and includes a very permissive parser that accepts most of the json extensions that I know of.

I would like to make serde-annotate work correctly with erased-serde as well, as I have a use case where number of different functions return their serializable result struct as a erased_serde::Serialize trait object. I must admit a lack of expertise here, but having erased_serde make some type information available to the serializer was the only solution I could find (See https://github.com/lowRISC/serde-annotate/pull/3 for the list of things I tried).

I need to take another look at your autoref-specialization case study document and see if I can make that work (I failed in my first attempt, but I think I need to try again).

I also saw your Pre-RFC: non-footgun non-static TypeId and I would work up a solution using something like same_as.

This PR represents my current solution. I'd like to find the right solution.

cfrantz commented 2 years ago

I discovered that I was using min_specialization incorrectly in my prior experiments. It was not clear to me that I needed my default impl to have the trait bound ?Sized + serde::Serialize (I had previously only been constraining on serde::Serialize).

Having overcome that misunderstanding, I was able to get annotations working with min_specialization as the base tech for letting my serializer find annotation information on T: serde::Serialize. I did not find a way to use min_specialization to allow my serializer to interact correctly with dyn erased_serde::Serialize objects, however, I did find a way to implement my own form of type erasure that seems to work for my purposes: I implemented serde::Serialize on the dyn Annotate trait object.

I do not think that your autoref-specialization technique applies to my use case: the serializer bounds the types will accept to ?Sized + serde::Serialize. I think that means the compiler won't be able to know about other traits possibly implemented for T and wont be able to choose among the available impls (please correct me if I'm mistaken).

cfrantz commented 1 year ago

FWIW, I don't thinks this belongs in erased-serde either. What I would like to find is a solution for interacting with the serde ecosystem (serde, erased-serde and typetag in particular) that doesn't involve horrible hacks like this.

As I mentioned in my previous note, I have a form of type-erasure implemented in my own library that works for one of my use cases. I don't think it will work together with typetag and I'd prefer not to create parallel versions of already-existing serde capabilities.

dtolnay commented 1 year ago

I am interested what you come up with, but don't expect it's a goal for any of the libraries you named to support this use case.