mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-05-06 03:17:56 +00:00
Merge pull request #678 from serde-rs/empty
Handle various degenerate cases
This commit is contained in:
+29
-13
@@ -509,14 +509,6 @@ fn deserialize_item_enum(
|
|||||||
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
|
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
|
||||||
};
|
};
|
||||||
|
|
||||||
let ignored_arm = if item_attrs.deny_unknown_fields() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(quote! {
|
|
||||||
__Field::__ignore => { Err(_serde::de::Error::end_of_stream()) }
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
// Match arms to extract a variant from a string
|
// Match arms to extract a variant from a string
|
||||||
let mut variant_arms = vec![];
|
let mut variant_arms = vec![];
|
||||||
for (i, variant) in variants.iter().filter(|variant| !variant.attrs.skip_deserializing()).enumerate() {
|
for (i, variant) in variants.iter().filter(|variant| !variant.attrs.skip_deserializing()).enumerate() {
|
||||||
@@ -536,7 +528,23 @@ fn deserialize_item_enum(
|
|||||||
};
|
};
|
||||||
variant_arms.push(arm);
|
variant_arms.push(arm);
|
||||||
}
|
}
|
||||||
variant_arms.extend(ignored_arm.into_iter());
|
|
||||||
|
let match_variant = if variant_arms.is_empty() {
|
||||||
|
// This is an empty enum like `enum Impossible {}` or an enum in which
|
||||||
|
// all variants have `#[serde(skip_deserializing)]`.
|
||||||
|
quote! {
|
||||||
|
// FIXME: Once we drop support for Rust 1.15:
|
||||||
|
// let Err(err) = visitor.visit_variant::<__Field>();
|
||||||
|
// Err(err)
|
||||||
|
visitor.visit_variant::<__Field>().map(|impossible| match impossible {})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
quote! {
|
||||||
|
match try!(visitor.visit_variant()) {
|
||||||
|
#(#variant_arms)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(impl_generics);
|
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(impl_generics);
|
||||||
|
|
||||||
@@ -551,9 +559,7 @@ fn deserialize_item_enum(
|
|||||||
fn visit_enum<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<#ty, __V::Error>
|
fn visit_enum<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<#ty, __V::Error>
|
||||||
where __V: _serde::de::VariantVisitor,
|
where __V: _serde::de::VariantVisitor,
|
||||||
{
|
{
|
||||||
match try!(visitor.visit_variant()) {
|
#match_variant
|
||||||
#(#variant_arms)*
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,7 +652,7 @@ fn deserialize_field_visitor(
|
|||||||
.map(|i| aster::id(format!("__field{}", i)))
|
.map(|i| aster::id(format!("__field{}", i)))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let ignore_variant = if item_attrs.deny_unknown_fields() {
|
let ignore_variant = if is_variant || item_attrs.deny_unknown_fields() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(quote!(__ignore,))
|
Some(quote!(__ignore,))
|
||||||
@@ -744,6 +750,16 @@ fn deserialize_map(
|
|||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
item_attrs: &attr::Item,
|
item_attrs: &attr::Item,
|
||||||
) -> Tokens {
|
) -> Tokens {
|
||||||
|
if fields.is_empty() && item_attrs.deny_unknown_fields() {
|
||||||
|
return quote! {
|
||||||
|
// FIXME: Once we drop support for Rust 1.15:
|
||||||
|
// let None::<__Field> = try!(visitor.visit_key());
|
||||||
|
try!(visitor.visit_key::<__Field>()).map(|impossible| match impossible {});
|
||||||
|
try!(visitor.end());
|
||||||
|
Ok(#struct_path {})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Create the field names for the fields.
|
// Create the field names for the fields.
|
||||||
let fields_names = fields.iter()
|
let fields_names = fields.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
|||||||
@@ -208,6 +208,85 @@ fn test_gen() {
|
|||||||
struct NonAsciiIdents {
|
struct NonAsciiIdents {
|
||||||
σ: f64
|
σ: f64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct EmptyBraced {}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
struct EmptyBracedDenyUnknown {}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct BracedSkipAll {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
f: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
struct BracedSkipAllDenyUnknown {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
f: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable-testing")]
|
||||||
|
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))]
|
||||||
|
struct EmptyTuple();
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable-testing")]
|
||||||
|
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
struct EmptyTupleDenyUnknown();
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct TupleSkipAll(#[serde(skip_deserializing)] u8);
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
struct TupleSkipAllDenyUnknown(#[serde(skip_deserializing)] u8);
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
enum EmptyEnum {}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
enum EmptyEnumDenyUnknown {}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
enum EnumSkipAll {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
Variant,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable-testing")]
|
||||||
|
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))]
|
||||||
|
enum EmptyVariants {
|
||||||
|
Braced {},
|
||||||
|
Tuple(),
|
||||||
|
BracedSkip {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
f: u8,
|
||||||
|
},
|
||||||
|
TupleSkip(#[serde(skip_deserializing)] u8),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "unstable-testing")]
|
||||||
|
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
enum EmptyVariantsDenyUnknown {
|
||||||
|
Braced {},
|
||||||
|
Tuple(),
|
||||||
|
BracedSkip {
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
f: u8,
|
||||||
|
},
|
||||||
|
TupleSkip(#[serde(skip_deserializing)] u8),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
struct UnitDenyUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
Reference in New Issue
Block a user