Skip to content

Commit

Permalink
ser: sequences: Introduce SeqSerializer newtype
Browse files Browse the repository at this point in the history
We're going to want to do something more complicated.

In particular, to handle nested arrays properly, we need to do some
work at the start and end of each array.

The `new` and (inherent) `end` methods of this newtype is where that
work will be done.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
(cherry picked from commit 147e6c7)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
  • Loading branch information
ijackson committed Nov 7, 2023
1 parent 319a9e2 commit 43ac661
Showing 1 changed file with 28 additions and 14 deletions.
42 changes: 28 additions & 14 deletions src/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub struct ConfigSerializer {
pub output: Config,
}

pub struct SeqSerializer<'a>(&'a mut ConfigSerializer);

impl ConfigSerializer {
fn serialize_primitive<T>(&mut self, value: T) -> Result<()>
where
Expand Down Expand Up @@ -85,10 +87,10 @@ impl ConfigSerializer {
impl<'a> ser::Serializer for &'a mut ConfigSerializer {
type Ok = ();
type Error = ConfigError;
type SerializeSeq = Self;
type SerializeTuple = Self;
type SerializeTupleStruct = Self;
type SerializeTupleVariant = Self;
type SerializeSeq = SeqSerializer<'a>;
type SerializeTuple = SeqSerializer<'a>;
type SerializeTupleStruct = SeqSerializer<'a>;
type SerializeTupleVariant = SeqSerializer<'a>;
type SerializeMap = Self;
type SerializeStruct = Self;
type SerializeStructVariant = Self;
Expand Down Expand Up @@ -159,7 +161,8 @@ impl<'a> ser::Serializer for &'a mut ConfigSerializer {
for byte in v {
seq.serialize_element(byte)?;
}
seq.end()
seq.end();
Ok(())
}

fn serialize_none(self) -> Result<Self::Ok> {
Expand Down Expand Up @@ -214,7 +217,7 @@ impl<'a> ser::Serializer for &'a mut ConfigSerializer {
}

fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
Ok(self)
SeqSerializer::new(self)
}

fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
Expand Down Expand Up @@ -260,25 +263,36 @@ impl<'a> ser::Serializer for &'a mut ConfigSerializer {
}
}

impl<'a> ser::SerializeSeq for &'a mut ConfigSerializer {
impl<'a> SeqSerializer<'a> {
fn new(inner: &'a mut ConfigSerializer) -> Result<Self> {
Ok(SeqSerializer(inner))
}

fn end(self) -> &'a mut ConfigSerializer {
self.0
}
}

impl<'a> ser::SerializeSeq for SeqSerializer<'a> {
type Ok = ();
type Error = ConfigError;

fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where
T: ?Sized + ser::Serialize,
{
self.inc_last_key_index()?;
value.serialize(&mut **self)?;
self.0.inc_last_key_index()?;
value.serialize(&mut *(self.0))?;
Ok(())
}

fn end(self) -> Result<Self::Ok> {
self.end();
Ok(())
}
}

impl<'a> ser::SerializeTuple for &'a mut ConfigSerializer {
impl<'a> ser::SerializeTuple for SeqSerializer<'a> {
type Ok = ();
type Error = ConfigError;

Expand All @@ -294,7 +308,7 @@ impl<'a> ser::SerializeTuple for &'a mut ConfigSerializer {
}
}

impl<'a> ser::SerializeTupleStruct for &'a mut ConfigSerializer {
impl<'a> ser::SerializeTupleStruct for SeqSerializer<'a> {
type Ok = ();
type Error = ConfigError;

Expand All @@ -310,7 +324,7 @@ impl<'a> ser::SerializeTupleStruct for &'a mut ConfigSerializer {
}
}

impl<'a> ser::SerializeTupleVariant for &'a mut ConfigSerializer {
impl<'a> ser::SerializeTupleVariant for SeqSerializer<'a> {
type Ok = ();
type Error = ConfigError;

Expand All @@ -322,8 +336,8 @@ impl<'a> ser::SerializeTupleVariant for &'a mut ConfigSerializer {
}

fn end(self) -> Result<Self::Ok> {
ser::SerializeSeq::end(&mut *self)?;
self.pop_key();
let inner = self.end();
inner.pop_key();
Ok(())
}
}
Expand Down

0 comments on commit 43ac661

Please sign in to comment.