Implement struct-like enum variant serialisation
Diff
src/lib.rs | 3 +++
src/ser.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 60 insertions(+), 4 deletions(-)
@@ -32,6 +32,7 @@ mod test {
Abc,
Def(i32),
Ghi(i32, i32, i32),
Jkl { a: i32, b: i32 },
}
#[derive(Serialize)]
@@ -44,6 +45,7 @@ mod test {
e: Test,
e2: Test,
e3: Test,
e4: Test,
t: (i32, i32, i32),
ts: Tup,
}
@@ -58,6 +60,7 @@ mod test {
e: Test::Abc,
e2: Test::Def(1999),
e3: Test::Ghi(16, 07, 1999),
e4: Test::Jkl { a: 16, b: 07 },
t: (16, 07, 1999),
ts: Tup(99, 100),
},
@@ -33,7 +33,7 @@ impl<'a> serde::Serializer for Serializer<'a> {
type SerializeTupleVariant = TupleVariantSerializer<'a>;
type SerializeMap = serde::ser::Impossible<Self::Ok, Self::Error>;
type SerializeStruct = StructSerializer<'a>;
type SerializeStructVariant = serde::ser::Impossible<Self::Ok, Self::Error>;
type SerializeStructVariant = StructVariantSerializer<'a>;
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
write_key_or_error!(0x01, self.key, self.output);
@@ -242,13 +242,28 @@ impl<'a> serde::Serializer for Serializer<'a> {
}
fn serialize_struct_variant(
self,
mut self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
todo!("struct variant")
if self.key.is_some() {
write_key_or_error!(0x03, self.key, self.output);
}
let mut doc_output = start_document(&mut self.output);
write_key_or_error!(0x03, Some(DocumentKey::Str(variant)), &mut doc_output);
let nested_doc_output = start_document(&mut doc_output);
Ok(StructVariantSerializer {
original_output: self.output,
nested_doc_output,
doc_output,
})
}
fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
@@ -326,6 +341,44 @@ impl<'a> serde::ser::SerializeTupleVariant for TupleVariantSerializer<'a> {
}
}
pub struct StructVariantSerializer<'a> {
original_output: &'a mut BytesMut,
nested_doc_output: BytesMut,
doc_output: BytesMut,
}
impl<'a> serde::ser::SerializeStructVariant for StructVariantSerializer<'a> {
type Ok = ();
type Error = <Serializer<'a> as serde::Serializer>::Error;
fn serialize_field<T: ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error>
where
T: Serialize,
{
value.serialize(Serializer {
key: Some(DocumentKey::Str(key)),
output: &mut self.nested_doc_output,
})?;
Ok(())
}
fn end(mut self) -> Result<Self::Ok, Self::Error> {
terminate_document(&mut self.doc_output, self.nested_doc_output);
terminate_document(self.original_output, self.doc_output);
Ok(())
}
}
pub struct TupleStructSerializer<'a> {
inner: SeqSerializer<'a>,
}