Macro to convert from/to "identical" enums?

I'm using a macro which generates enums from a schema.graphql file. One limitation of this macro is that I can't use #derive on the generated enums/structs (e.g. #[derive(FromSqlRow)]). So, as recommended by the crate author, I resorted to writing my own identical enums with From implementations to convert back and forth, e.g.:

impl From<&TransactionType> for models::TransactionType {
    fn from(x: &TransactionType) -> models::TransactionType {
        match x {
            TransactionType::Deposit => models::TransactionType::Deposit,
            TransactionType::Withdraw => models::TransactionType::Withdraw,
            TransactionType::Payout => models::TransactionType::Payout,
            TransactionType::Rollback => models::TransactionType::Rollback,
        }
    }
}

impl From<&models::TransactionType> for TransactionType {
    fn from(x: &models::TransactionType) -> TransactionType {
        match x {
            models::TransactionType::Deposit => TransactionType::Deposit,
            models::TransactionType::Withdraw => TransactionType::Withdraw,
            models::TransactionType::Payout => TransactionType::Payout,
            models::TransactionType::Rollback => TransactionType::Rollback,
        }
    }
}

I was wondering if there existed a macro that could automate the above and if not, if it was feasible for a newbie to write one.

Thanks!

I adapted a macro I found on Stackoverflow:

macro_rules! convert_enum {
    ($src: ty, $dst: ty, $($variant: ident,)+) => {
        impl From<&$src> for $dst {
            fn from(src: &$src) -> Self {
                match src {
                    $(<$src>::$variant => Self::$variant,)*
                }
            }
        }
        impl From<&$dst> for $src {
            fn from(src: &$dst) -> Self {
                match src {
                    $(<$dst>::$variant => Self::$variant,)*
                }
            }
        }
    }
}

convert_enum!(TransactionType, models::TransactionType, Deposit, Withdraw, Payout, Rollback,);

A lot better but still requires hard coding the enum variants in the macro call. I wonder if that part could be handled by the macro as well?

I don't think this helps with your particular situation, but mentioning for the sake of it in case it helps.

Related to this question, frunk is a crate exactly for this kind of "identical" struct or enum transformation. With frunk-enum it works for identical enums too.

Unfortunately, it requires #[derive(LabelledGenericEnum)] to record the fields / types of each involved enum and won't work in general without that. If you can't derive anything else, then this won't really help either.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.