Use serde's untagged with generic enum

I have the JSON structure of two API responses which are similar to each other. They share most of the fields. So I implemented the logic code to use a common function that can handle both API responses.

So I have the following setup

#[derive(Debug, Clone, serde::Deserialize)]
enum GenericBSCTransactionResponseResult<T> {

#[derive(Debug, serde::Deserialize)]
struct BSCTransactionResponse<T> {
    status: String,
    message: String,
    result: GenericBSCTransactionResponseResult::<T>,

trait CompatibleTransactionResponse<T> {
    fn status(&self) -> String;
    fn message(&self) -> String;
    fn result(&self) -> GenericBSCTransactionResponseResult::<T>;

impl CompatibleTransactionResponse<BSCNormalTransactionResponseSuccessVariantResult> for BSCTransactionResponse<BSCNormalTransactionResponseSuccessVariantResult>
    fn status(&self) -> String {

    fn message(&self) -> String {

    fn result(&self) -> GenericBSCTransactionResponseResult::<BSCNormalTransactionResponseSuccessVariantResult> {

BSCTransactionResponse is the entry point JSON structure to be deserialized by serde. CompatibleTransactionResponse is a trait to satisfy Rust's compiler when I implement generic function to handle such thing. The following is my function.

fn get_list_transactions<R, J>(address: &str) -> Result<Vec::<R>, AppError>
    R: serde::de::DeserializeOwned,
    J: CompatibleTransactionResponse::<R> + serde::de::DeserializeOwned
    ... // preparation
    ... // make HTTP request
    match response.json::<J>() {   // I use isahc, but it doesn't matter, json string returned properly, same error shown at the end from serde's json deserialization
        ... // Err(e) is caught here

At the consuming side, the following is the way to use such function

fn get_list_normal_transactions(address: &str) -> Result<Vec::<BSCNormalTransactionResponseSuccessVariantResult>, AppError>
    type ResultType = BSCNormalTransactionResponseSuccessVariantResult;
    type JsonType = BSCTransactionResponse::<ResultType>;

    get_list_transactions::<ResultType, JsonType>(address)

Multiple of actual structs that hold the information i.e. BSCNormalTransactionResponseSuccessVariantResult, and BSCInternalTransactionResponseSuccessVariantResult would be just normal struct that has #[derive(Debug, serde::Deserialize)], nothing fancy for these.

The error I got at runtime is

Error("data did not match any variant of untagged enum GenericBSCTransactionResponseResult", line: 1, column: 313387)

which comes from serde's deserialize_untagged_enum function (linked in to specific version I use, but it's the same as it is for latest version).

So at this point, what did I miss or did wrongly. I found this to be as close to at least confirm serde should support generic struct for JSON deserialization, but can't be sure for generic enum.

Question is: How do I fix this in order to use serde's deserialization + untagged with generic enum? Any suggestion would be very welcome!

What I have already worked. It turns out it's my mistake for a particular field inside a struct that holds actual data which doesn't align with the type it should be.

In short, my code setup works fine. There is no issue with serde. It works fine with generic enum.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.