Skip to content

Commit

Permalink
Implement serialization of flattened tuple variants of externally tag…
Browse files Browse the repository at this point in the history
…ged enums

The Container struct

  struct Container {
    #[serde(flatten)]
    enum_field: Enum,
  }
  enum Enum {
    Tuple(u32, u32),
  }

now can be serialized to JSON as

  { "enum_field": [1, 2] }

Deserialization already works

Fixes (1):
    flatten::enum_::externally_tagged::tuple
  • Loading branch information
Mingun committed Jun 8, 2023
1 parent f71f370 commit 6c76840
Showing 1 changed file with 50 additions and 3 deletions.
53 changes: 50 additions & 3 deletions serde/src/private/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ where
type SerializeTupleStruct = Impossible<Self::Ok, M::Error>;
type SerializeMap = FlatMapSerializeMap<'a, M>;
type SerializeStruct = FlatMapSerializeStruct<'a, M>;
type SerializeTupleVariant = Impossible<Self::Ok, M::Error>;
type SerializeTupleVariant = FlatMapSerializeTupleVariantAsMapValue<'a, M>;
type SerializeStructVariant = FlatMapSerializeStructVariantAsMapValue<'a, M>;

fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
Expand Down Expand Up @@ -1157,10 +1157,11 @@ where
self,
_: &'static str,
_: u32,
_: &'static str,
variant: &'static str,
_: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
Err(Self::bad_type(Unsupported::Enum))
try!(self.0.serialize_key(variant));
Ok(FlatMapSerializeTupleVariantAsMapValue::new(self.0))
}

fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
Expand Down Expand Up @@ -1259,6 +1260,52 @@ where
}
}

////////////////////////////////////////////////////////////////////////////////////////////////////

#[cfg(any(feature = "std", feature = "alloc"))]
pub struct FlatMapSerializeTupleVariantAsMapValue<'a, M: 'a> {
map: &'a mut M,
fields: Vec<Content>,
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, M> FlatMapSerializeTupleVariantAsMapValue<'a, M>
where
M: SerializeMap + 'a,
{
fn new(map: &'a mut M) -> Self {
FlatMapSerializeTupleVariantAsMapValue {
map: map,
fields: Vec::new(),
}
}
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, M> ser::SerializeTupleVariant for FlatMapSerializeTupleVariantAsMapValue<'a, M>
where
M: SerializeMap + 'a,
{
type Ok = ();
type Error = M::Error;

fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
let value = try!(value.serialize(ContentSerializer::<M::Error>::new()));
self.fields.push(value);
Ok(())
}

fn end(self) -> Result<(), Self::Error> {
try!(self.map.serialize_value(&Content::Seq(self.fields)));
Ok(())
}
}

////////////////////////////////////////////////////////////////////////////////////////////////////

#[cfg(any(feature = "std", feature = "alloc"))]
pub struct FlatMapSerializeStructVariantAsMapValue<'a, M: 'a> {
map: &'a mut M,
Expand Down

0 comments on commit 6c76840

Please sign in to comment.