Serialize nested tagged enum

I have a nested enum, and I am trying to implement Serialize so that the inner enum is flattened. Here is a simplified example:

use serde;
use serde::ser::{Serialize, SerializeStruct, Serializer};

#[derive(Debug, serde::Serialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum Wrapped {
    V1 { a: u8 },
    V2 { a: u8, b: u8 },
}

pub enum Wrapper {
    W(usize, Wrapped),
    V3 { a: u8 },
}

// expected results with a JSON serializer:
// Wrapper::W(0, Wrapped::V1{a:1})
// {"type": "v1", "id": 0, "a": 1}
//
// Wrapper::V3{a:1}
// {"type": "v3", "a": 1}
impl Serialize for Wrapper {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match self {
            Wrapper::W(id, wrapped) => {
                // add an `id` field to the serialized `wrapped`
            }
            Wrapper::V3{a} => {
                let mut state = serializer.serialize_struct("V3", 2)?;
                state.serialize_field("type", "v3");
                state.serialize_field("a", a)?;
                state.end()
            }
        }
    }
}

Could anyone point me to the right direction?

I got it working with:

    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        #[derive(Debug, serde::Serialize)]
        struct WrappedWithId<'a> {
            id: usize,
            #[serde(flatten)]
            w: &'a Wrapped
        }
    
        match self {
            Wrapper::W(id, wrapped) => {
                WrappedWithId{
                    id: *id,
                    w: wrapped
                }.serialize(serializer)
            }
            Wrapper::V3{a} => {
                let mut state = serializer.serialize_struct("V3", 2)?;
                state.serialize_field("type", "v3");
                state.serialize_field("a", a)?;
                state.end()
            }
        }
    }

This approach allows me to use the derived serializer on the wrapped type, but it forces me to hand write the serializer for all the other variants on the wrapper (like V3 here). I am wondering if there is a solution to auto generate the serializer for those as well.

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.