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