Serde serialization / deserialization via another implementation?

Hi all,

I've read the docs at Custom serialization · Serde and the links therein.

I have an enum (but it could as well be a struct) that implements ToString (I could also implement Into<String> if necessary) and From<String>. Given that I have these, is there a simple way to (ideally with macros) implement the serde serializers? I started writing out the manual boilerplate to do this explicitly and it is very longwinded... especially on the deserialize side which requires a visitor.

(There's a whole theory behind this sort of thing in scala / haskell to do with covariant and contravariant higher kinded traits, but) limiting and grounding ourselves to just serde, if we have an Into<Foo> for Bar and there exists a Serialize for Foo then we should be able to derive a Serialize for Bar. Likewise if we have a From<Foo> for Bar (or even a TryFrom<Foo> for Bar) then we should be able to derive a Deserialize for Bar. Obviously we wouldn't want these things to be automatically derived, the choice of should be deemed the canonical form should be left to the owner of the type to decide.

Does something, ideally a macro, already exist to do that without having to write a lot of boilerplate? I would imagine it would be called something like a "delegate" serializer... but my google and rustdoc skillz are failing me.

Yes, this is built in:

#[derive(Serialize)]
#[serde(into = "Foo")]
struct Bar {...}

There are many attributes that can customize derive(Serialize) for delegation and other purposes.

Also, if you want to do such a conversion solely for serialization purposes, without depending on an Into implementation existing, you can simply call Foo::serialize() from inside an impl Serialize for Bar. Using this technique, you rarely need to write a serde visitor.

Unless every possible string is valid, you should probably be implementing TryFrom<String> (or FromStr) instead of String.

1 Like

oh, excellent! I'm actually having a hard time finding the full list of attributes that can be used with serde on both the serialise and deserialize side, if you're aware of something like that it would be greatly appreciated. I have found a few by looking through the docs, but no definitive list. Is there a from or try_from equivalent for deserialization?

The docs page I linked to, or more precisely its three subsections (Container attributes, Variant attributes, and Field attributes), are the definitive list. And yes, there is a from attribute, and try_from too.

1 Like

ah, great! I will bookmark this and probably give it a full read through, really fantastic stuff. And I see from is indeed supported.