Search code examples
rustserializationserde

How to access the main Serializer when using a separated Serializer for structs


When I write a Serializer for any data format, I have the option to separate the Serializers for the more complex types.

pub struct Serializer {
    output: String,
}

impl<'a> ser::Serializer for &'a mut Serializer {
     type Ok = ();
     type Error = Error;

     type SerializeStruct = MyStructSerializer; // separate Serializer for structs

     ...
}

If I take that approach and I need to serialize basic types inside the serializer for the complex type, I need to call serialize() with a reference to the main serializer, which is not available there.

pub struct MyStructSerializer {
}

impl<'a> ser::SerializeStructVariant for &'a mut MyStructSerializer {
    type Ok = Value;
    type Error = Error;

    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
    where
        T: ?Sized + Serialize,
    {
        key.serialize(&mut **self)?; // Need reference to Serializer here
        value.serialize(&mut **self)?; // Need reference to Serializer here
        Ok(())
    }
    ...
}

How do I handle this?


Solution

  • You can have a reference to the serializer in MyStructSerializer:

    pub struct MyStructSerializer<'a> {
        serializer: &'a mut Serializer,
    }
    
    impl<'a> ser::Serializer for &'a mut Serializer {
        type Ok = ();
        type Error = Error;
    
        type SerializeStruct = MyStructSerializer<'a>; // separate Serializer for structs
    
        // ...
    
        fn serialize_struct_variant(
            self,
            name: &'static str,
            variant_index: u32,
            variant: &'static str,
            len: usize,
        ) -> Result<Self::SerializeStructVariant, Self::Error>
        {
            MyStructSerializer { serializer: self }
        }
        // ...
    }