Problems with implementing serde::ser::Serializer

UPDATE: I put together a minimal example.

I want to write a no-std compatible MessagePack serializer/deserializer. So far I got most of the serialization working, but I am struggling with serializing structs, sequences and maps using serde.
I copied a lot from serde_json_core, but these parts don't seem to work.

This is my Serializer struct:

    pub(crate) struct Serializer<'a> {
        buf: &'a mut [u8],
        pos: usize,
    }

and my sequence serializer struct:

    pub struct SerializeSeq<'a> { ser: &'a mut Serializer<'a> }

    impl<'a> ser::SerializeSeq for SerializeSeq<'a> {
        type Ok = ();
        type Error = Error;
        fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<Self::Ok, Self::Error>
        where T: ser::Serialize {
            value.serialize(&mut *self.ser)?;
            Ok(())
        }
        fn end(self) -> Result<Self::Ok, Self::Error> {
            Ok(())
        }
    }

It's just like in serde_json_serde::ser::seq, but it fails to compile with this message:

error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
  --> src/lib.rs:23:25
   |
23 |         value.serialize(&mut *self.ser)?;
   |                         ^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 18:5...
  --> src/lib.rs:18:5
   |
18 | /     fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<Self::Ok, Self::Error>
19 | |     where
20 | |         T: ser::Serialize
21 | |     {
...  |
24 | |         Ok(())
25 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> src/lib.rs:23:25
   |
23 |         value.serialize(&mut *self.ser)?;
   |                         ^^^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 14:6...
  --> src/lib.rs:14:6
   |
14 | impl<'a> ser::SerializeSeq for SerializeSeq<'a> {
   |      ^^
note: ...so that the types are compatible
  --> src/lib.rs:23:15
   |
23 |         value.serialize(&mut *self.ser)?;
   |               ^^^^^^^^^
   = note: expected `serde::Serializer`
              found `serde::Serializer`

I also tried passing &mut self.ser, mut *self.ser and self.ser, but they all fail to compile with different error messages. Obviously it has something to do with the lifetimes of the serializer and it's buffer, but I don't know how to solve this.

The serializer impl looks like this:

    impl<'a> ser::Serializer for &'a mut Serializer<'a> {
        type Ok = ();
        type Error = Error;
        type SerializeSeq = SerializeSeq<'a>;
        type SerializeTuple = SerializeSeq<'a>;
        // ...
        fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
            Ok(SerializeSeq::new(self))
        }
    }

To be honest, your post looks a bit confusing to me, but looking at your error message it may have something to do with passing the wrong type of "Serializer" as a parameter (since I see both structs and traits named "Serializer"). What you could do is remove all the use statements and prefixing types manually, it may help you see what goes where. If that doesnt work, please post the full new version of your code.

The problem is that you are implementing Serde's Serializer trait for &mut Serializer but then trying to serialize into a &mut &mut Serializer (type of self.ser is &mut Serializer so type of &mut self.ser is &mut &mut Serializer).

What you probably want is value.serialize(&mut *self.ser) - i.e. you explicitly dereference the reference and then reborrow it again to get the correct type. That's a common idiom in implementing Serde data formats, and if that does not work, there's something else wrong with your code.

You should post a minimal, compilable, self-contained example (preferably on the Playground), so that others willing to help you can investigate what the problem actually is.

That is what I thought, but doesn't &mut *self.ser produce a &mut &mut Serializer again?

I put together a minimal example. It has a lot of boilerplate code to implement serde's ser::Serializer trait, but I think this can be ignored. Just the bit at the top is causing me problems at the moment.

I probably just have to change the lifetime annotations somehow, but this concept is still somewhat confusing to me as I don't have any experience in it from other languages...

Any help would be greatly appreciated :upside_down_face:!

The error message shows different code from the code you've posted. Try your original code again and make sure all the files are saved after edit.

1 Like

You are right. The error message was from one of the things I tried that also did not work. But the minimal example I gave contains the correct code.

I only difference to serde_json_core is that my Serializer does not own the internal buffer and therefore needs a lifetime annotation. This causes SerializeSeq.ser to have the type &'a mut Serializer<'a> which leads to these errors I think. I tried introducing different lifetimes for the reference and the serializer (i.e. &'b mut Serializer<'a>), but that did not help.

PS: I edited the error message in the original post to match the code I gave.

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.