How to serialize a `struct` to a hierarchy map?

I have a struct:

struct MyStruct {
    key_outer: String,
    key_inner: String,
    data: String
}

and an instance of it:

let my_struct = MyStruct {
    key_outer: "key_outer".into(),
    key_inner: "key_inner".into(),
    data: "my-data".into(),
}

How can I implement the trait Serialize for it, so the output of the instance:

serde_json::to_string(&my_struct).unwrap()
///expected output
{"key_outer": {"key_inner": "my-data"}}

I tried this, it doesn't work:

impl Serialize for MyStruct
where
    T: Serialize,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut inner2 = serializer.serialize_map(Some(1))?;
        inner2.serialize_entry(&self.key_inner, &self.data)?;
        inner2.end();
        let mut inner1 = serializer.serialize_map(Some(1))?;
        inner1.serialize_entry(&self.key_outer, &inner2)?;
        inner1.end();
        
    }
}

A bit more boilerplate…

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

struct MyStruct {
    key_outer: String,
    key_inner: String,
    data: String,
}

fn main() {
    let my_struct = MyStruct {
        key_outer: "key_outer".into(),
        key_inner: "key_inner".into(),
        data: "my-data".into(),
    };

    assert_eq!(serde_json::to_string(&my_struct).unwrap(), r#"{"key_outer":{"key_inner":"my-data"}}"#);
}

impl Serialize for MyStruct {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut outer_map = serializer.serialize_map(Some(1))?;
        outer_map.serialize_entry(&self.key_outer, &{
            struct InnerMap<'a> {
                key_inner: &'a String,
                data: &'a String,
            }
            impl Serialize for InnerMap<'_> {
                fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
                where
                    S: Serializer,
                {
                    let mut inner_map = serializer.serialize_map(Some(1))?;
                    inner_map.serialize_entry(self.key_inner, self.data)?;
                    inner_map.end()
                }
            }
            InnerMap {
                key_inner: &self.key_inner,
                data: &self.data,
            }
        })?;
        outer_map.end()
    }
}
3 Likes