2 ms·
There's a well-known (and frequently encouraged) workaround for the orphan rule: Create a wrapper type. Let's say you have one library with: pub struct Ty
by ekidd 7mo ago
There's a well-known (and frequently encouraged) workaround for the orphan rule: Create a wrapper type.
Let's say you have one library with:
pub struct TypeWithSomeSerialization { /* public fields here */ }
And you want to define a custom serialization. In this case, you can write:
pub struct TypeWithDifferentSerialization(TypeWithSomeSerialization)
Then you just implement Serialize and Deserialize for TypeWithDifferentSerialization.
This cover most occasional cases where you need to work around the orphan rule. And semantically, it's pretty reasonable: If a type behaves differently, then it really isn't the same type.
The alternative is to have a situation where you have library A define a data type, library B define an interface, and library C implement the interface from B for the type from A. Very few languages actually allow this, because you run into the problem where library D tries to do the same thing library C did, but does it differently. There are workarounds, but they add complexity and confusion, which may not be worth it.
- dhosek 7mo agoThe gotcha is what happens when TypeWithSomeSerialization is not something you’re using directly but is contained within SomeOtherTypeWithSomeSerialization which you are using directly. Then things get messy.
- bigfishrunning 7mo agoIn that case, wrap a reference maybe? pub struct TypeWithDifferentSerialization(&TypeWithSomeSerialization)
- deathanatos 7mo agoWe can't say with certainty how an unspecified in-the-future library might work, so I'm going to use serde as a stand-in. You can implement `Serialize` for a wrapper type and still serialize `SomeOtherTypeWithSomeSerialization` (which might be used by the type being wrapper directly or indirectly) differently. It might not be derivable, of course, but "I don't want the default" sort of makes that a given.