Fix serializing externally-tagged enum
representations
This commit is contained in:
parent
4b6afc9c72
commit
4a3a32dc3a
143
src/serde/ser.rs
143
src/serde/ser.rs
@ -103,10 +103,16 @@ impl Serializer for &mut DynamicSerializer {
|
|||||||
type SerializeSeq = DynamicSerializer;
|
type SerializeSeq = DynamicSerializer;
|
||||||
type SerializeTuple = DynamicSerializer;
|
type SerializeTuple = DynamicSerializer;
|
||||||
type SerializeTupleStruct = DynamicSerializer;
|
type SerializeTupleStruct = DynamicSerializer;
|
||||||
type SerializeTupleVariant = DynamicSerializer;
|
#[cfg(not(any(feature = "no_object", feature = "no_index")))]
|
||||||
|
type SerializeTupleVariant = TupleVariantSerializer;
|
||||||
|
#[cfg(any(feature = "no_object", feature = "no_index"))]
|
||||||
|
type SerializeTupleVariant = serde::ser::Impossible<Dynamic, Box<EvalAltResult>>;
|
||||||
type SerializeMap = DynamicSerializer;
|
type SerializeMap = DynamicSerializer;
|
||||||
type SerializeStruct = DynamicSerializer;
|
type SerializeStruct = DynamicSerializer;
|
||||||
type SerializeStructVariant = DynamicSerializer;
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
type SerializeStructVariant = StructVariantSerializer;
|
||||||
|
#[cfg(feature = "no_object")]
|
||||||
|
type SerializeStructVariant = serde::ser::Impossible<Dynamic, Box<EvalAltResult>>;
|
||||||
|
|
||||||
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Box<EvalAltResult>> {
|
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||||
Ok(v.into())
|
Ok(v.into())
|
||||||
@ -244,10 +250,20 @@ impl Serializer for &mut DynamicSerializer {
|
|||||||
self,
|
self,
|
||||||
_name: &'static str,
|
_name: &'static str,
|
||||||
_variant_index: u32,
|
_variant_index: u32,
|
||||||
_variant: &'static str,
|
variant: &'static str,
|
||||||
value: &T,
|
value: &T,
|
||||||
) -> Result<Self::Ok, Box<EvalAltResult>> {
|
) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||||
value.serialize(&mut *self)
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
{
|
||||||
|
let content = to_dynamic(value)?;
|
||||||
|
make_variant(variant, content)
|
||||||
|
}
|
||||||
|
#[cfg(feature = "no_object")]
|
||||||
|
return Err(Box::new(EvalAltResult::ErrorMismatchOutputType(
|
||||||
|
"Dynamic".into(),
|
||||||
|
"map".into(),
|
||||||
|
Position::none(),
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Box<EvalAltResult>> {
|
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Box<EvalAltResult>> {
|
||||||
@ -277,10 +293,26 @@ impl Serializer for &mut DynamicSerializer {
|
|||||||
self,
|
self,
|
||||||
_name: &'static str,
|
_name: &'static str,
|
||||||
_variant_index: u32,
|
_variant_index: u32,
|
||||||
_variant: &'static str,
|
variant: &'static str,
|
||||||
len: usize,
|
len: usize,
|
||||||
) -> Result<Self::SerializeTupleVariant, Box<EvalAltResult>> {
|
) -> Result<Self::SerializeTupleVariant, Box<EvalAltResult>> {
|
||||||
self.serialize_seq(Some(len))
|
#[cfg(not(any(feature = "no_object", feature = "no_index")))]
|
||||||
|
return Ok(TupleVariantSerializer {
|
||||||
|
variant,
|
||||||
|
array: Array::with_capacity(len),
|
||||||
|
});
|
||||||
|
#[cfg(any(feature = "no_object", feature = "no_index"))]
|
||||||
|
{
|
||||||
|
#[cfg(feature = "no_object")]
|
||||||
|
let err_type = "map";
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
let err_type = "array";
|
||||||
|
Err(Box::new(EvalAltResult::ErrorMismatchOutputType(
|
||||||
|
"Dynamic".into(),
|
||||||
|
err_type.into(),
|
||||||
|
Position::none(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Box<EvalAltResult>> {
|
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Box<EvalAltResult>> {
|
||||||
@ -306,10 +338,20 @@ impl Serializer for &mut DynamicSerializer {
|
|||||||
self,
|
self,
|
||||||
_name: &'static str,
|
_name: &'static str,
|
||||||
_variant_index: u32,
|
_variant_index: u32,
|
||||||
_variant: &'static str,
|
variant: &'static str,
|
||||||
len: usize,
|
len: usize,
|
||||||
) -> Result<Self::SerializeStructVariant, Box<EvalAltResult>> {
|
) -> Result<Self::SerializeStructVariant, Box<EvalAltResult>> {
|
||||||
self.serialize_map(Some(len))
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
return Ok(StructVariantSerializer {
|
||||||
|
variant,
|
||||||
|
map: Map::with_capacity(len),
|
||||||
|
});
|
||||||
|
#[cfg(feature = "no_object")]
|
||||||
|
return Err(Box::new(EvalAltResult::ErrorMismatchOutputType(
|
||||||
|
"Dynamic".into(),
|
||||||
|
"map".into(),
|
||||||
|
Position::none(),
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,33 +437,6 @@ impl SerializeTupleStruct for DynamicSerializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SerializeTupleVariant for DynamicSerializer {
|
|
||||||
type Ok = Dynamic;
|
|
||||||
type Error = Box<EvalAltResult>;
|
|
||||||
|
|
||||||
fn serialize_field<T: ?Sized + Serialize>(
|
|
||||||
&mut self,
|
|
||||||
value: &T,
|
|
||||||
) -> Result<(), Box<EvalAltResult>> {
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
|
||||||
{
|
|
||||||
let value = value.serialize(&mut *self)?;
|
|
||||||
let arr = self.value.downcast_mut::<Array>().unwrap();
|
|
||||||
arr.push(value);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
#[cfg(feature = "no_index")]
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
|
||||||
return Ok(self.value);
|
|
||||||
#[cfg(feature = "no_index")]
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SerializeMap for DynamicSerializer {
|
impl SerializeMap for DynamicSerializer {
|
||||||
type Ok = Dynamic;
|
type Ok = Dynamic;
|
||||||
type Error = Box<EvalAltResult>;
|
type Error = Box<EvalAltResult>;
|
||||||
@ -520,7 +535,39 @@ impl SerializeStruct for DynamicSerializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SerializeStructVariant for DynamicSerializer {
|
#[cfg(not(any(feature = "no_object", feature = "no_index")))]
|
||||||
|
pub struct TupleVariantSerializer {
|
||||||
|
variant: &'static str,
|
||||||
|
array: Array,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "no_object", feature = "no_index")))]
|
||||||
|
impl SerializeTupleVariant for TupleVariantSerializer {
|
||||||
|
type Ok = Dynamic;
|
||||||
|
type Error = Box<EvalAltResult>;
|
||||||
|
|
||||||
|
fn serialize_field<T: ?Sized + Serialize>(
|
||||||
|
&mut self,
|
||||||
|
value: &T,
|
||||||
|
) -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let value = to_dynamic(value)?;
|
||||||
|
self.array.push(value);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||||
|
make_variant(self.variant, self.array.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
pub struct StructVariantSerializer {
|
||||||
|
variant: &'static str,
|
||||||
|
map: Map,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
impl SerializeStructVariant for StructVariantSerializer {
|
||||||
type Ok = Dynamic;
|
type Ok = Dynamic;
|
||||||
type Error = Box<EvalAltResult>;
|
type Error = Box<EvalAltResult>;
|
||||||
|
|
||||||
@ -529,21 +576,19 @@ impl SerializeStructVariant for DynamicSerializer {
|
|||||||
key: &'static str,
|
key: &'static str,
|
||||||
value: &T,
|
value: &T,
|
||||||
) -> Result<(), Box<EvalAltResult>> {
|
) -> Result<(), Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_object"))]
|
let value = to_dynamic(value)?;
|
||||||
{
|
self.map.insert(key.into(), value);
|
||||||
let value = value.serialize(&mut *self)?;
|
Ok(())
|
||||||
let map = self.value.downcast_mut::<Map>().unwrap();
|
|
||||||
map.insert(key.into(), value);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
#[cfg(feature = "no_object")]
|
|
||||||
unreachable!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
fn end(self) -> Result<Self::Ok, Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_object"))]
|
make_variant(self.variant, self.map.into())
|
||||||
return Ok(self.value);
|
|
||||||
#[cfg(feature = "no_object")]
|
|
||||||
unreachable!()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
fn make_variant(variant: &'static str, value: Dynamic) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
let mut map = Map::with_capacity(1);
|
||||||
|
map.insert(variant.into(), value);
|
||||||
|
Ok(map.into())
|
||||||
|
}
|
||||||
|
@ -135,7 +135,6 @@ fn test_serde_ser_unit_enum() -> Result<(), Box<EvalAltResult>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore = "failing test"]
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn test_serde_ser_externally_tagged_enum() -> Result<(), Box<EvalAltResult>> {
|
fn test_serde_ser_externally_tagged_enum() -> Result<(), Box<EvalAltResult>> {
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user