How to use "flatten" like thing in custom Serialize and Deserialize

Solution 1:

You could try doing something like this for Serialize and something similar for Deserialize:

struct FakeStructFlatteningSerializer<'a, SS: SerializeStruct>(&'a mut SS);

impl Serializer<'a, SS: SerializeStruct> for FakeStructFlatteningSerializer<'a, SS> {
    type Ok = ();
    type Error = SS::Error;
    type SerializeStruct = FakeStructFlatteningSerializeStruct<'a, SS>;
    
    // return Impossible for everything else
    
    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct, Self::Error> {
        // ignore name and len!
        Ok(FakeStructFlatteningSerializeStruct(self.0))
    }
}

struct FakeStructFlatteningSerializeStruct<'a, SS: SerializeStruct>(&'a mut SS);

impl<'a, SS: SerializeStruct> SerializeStruct for FakeStructFlatteningSerializeStruct<'a, SS> {
    type Ok = ();
    type Error = SS::Error;

    fn serialize_field<T: Serialize + ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> {
        self.0.serialize_field(key, value)
    }
    
    fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> {
        self.0.skip_field(key)
    }
    
    fn end(self) -> Result<Self::Ok, Self::Error> {
        // ignore!
        Ok(())
    }
}



impl Serialize for TopLevel {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        // len needs to include the flattened fields
        let mut do_struct = serializer.serialize_struct("Named", 3)?;
        do_struct.serialize_field("somefield1", &self.somefield1)?;
        self.nested.serialize(FakeStructFlatteningSerializer(&mut do_struct));
        return do_struct.end();
    }
}

You could alternatively try to figure out how Serde does it; this might be where: https://github.com/serde-rs/serde/blob/dc0c0dcba17dd8732cd8721a7ef556afcb04c6c0/serde_derive/src/ser.rs#L953-L1037, https://github.com/serde-rs/serde/blob/fb2fe409c8f7ad6c95e3096e5e9ede865c8cfb49/serde_derive/src/de.rs#L2560-L2578