I have an enum (imported from an external crate) that is called ExtEnum
.
In my project I implemented a serde
module called extenum_fromstr
for it and I use it to de/serialize ExtEnum
like so:
#[derive(Serialize, Deserialize)]
struct SomeStruct {
#[serde(with = "extenum_fromstr")]
ext_enum: ExtEnum,
...
}
This works fine.
Now, I have a different enum, let's call it MyEnum
that can be converted to ExtEnum
because it implements impl TryFrom<ExtEnum> for MyEnum
and impl TryFrom<MyEnum> for ExtEnum
.
I want to implement serde
for MyEnum
to behave just like the serde
implementation for ExtEnum
by taking advantage of the fact that I can convert MyEnum
to ExtEnum
.
Could I achieve this using only serde
attributes? Something like:
#[serde(from = "ExtEnum", into = "ExtEnum", with = "extenum_fromstr")]
enum MyEnum {
...
}
This does not compile because with
is not a valid container attribute. But is there a way to achieve this?
Ok, once again, we have:
mod ext { pub enum Enum; }
mod extenum_fromstr {
pub fn deserialize(/* .. */) { .. }
}
impl TryFrom<ext::Enum> for My { .. }
#[serde(..)] // how to reuse TryFrom & deserialize?
enum My { .. }
Suggested strategy:
Deserialize
for an intermediate Helper
type:
#[serde(with = "extenum_fromstr")]
TryFrom<Helper> for My
TryFrom<ext::Enum>
)My
as one that can be deserialized through Helper
#[serde(try_from = "Helper")]
You can find the code with explanation on the playground.