mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-13 21:51:04 +00:00
Reuse a single ContentRefDeserializer throughout untagged enum deserialization
This commit is contained in:
@@ -2193,6 +2193,14 @@ mod content {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a, 'de: 'a, E> Copy for ContentRefDeserializer<'a, 'de, E> {}
|
||||||
|
|
||||||
|
impl<'a, 'de: 'a, E> Clone for ContentRefDeserializer<'a, 'de, E> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
*self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct EnumRefDeserializer<'a, 'de: 'a, E>
|
struct EnumRefDeserializer<'a, 'de: 'a, E>
|
||||||
where
|
where
|
||||||
E: de::Error,
|
E: de::Error,
|
||||||
|
|||||||
+7
-15
@@ -1172,13 +1172,7 @@ fn deserialize_enum(
|
|||||||
Some(variant_idx) => {
|
Some(variant_idx) => {
|
||||||
let (tagged, untagged) = variants.split_at(variant_idx);
|
let (tagged, untagged) = variants.split_at(variant_idx);
|
||||||
let tagged_frag = Expr(deserialize_homogeneous_enum(params, tagged, cattrs));
|
let tagged_frag = Expr(deserialize_homogeneous_enum(params, tagged, cattrs));
|
||||||
let tagged_frag = |deserializer| {
|
deserialize_untagged_enum_after(params, untagged, cattrs, Some(tagged_frag))
|
||||||
Some(Expr(quote_block! {
|
|
||||||
let __deserializer = #deserializer;
|
|
||||||
#tagged_frag
|
|
||||||
}))
|
|
||||||
};
|
|
||||||
deserialize_untagged_enum_after(params, untagged, cattrs, tagged_frag)
|
|
||||||
}
|
}
|
||||||
None => deserialize_homogeneous_enum(params, variants, cattrs),
|
None => deserialize_homogeneous_enum(params, variants, cattrs),
|
||||||
}
|
}
|
||||||
@@ -1689,17 +1683,16 @@ fn deserialize_untagged_enum(
|
|||||||
variants: &[Variant],
|
variants: &[Variant],
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
deserialize_untagged_enum_after(params, variants, cattrs, |_| None)
|
let first_attempt = None;
|
||||||
|
deserialize_untagged_enum_after(params, variants, cattrs, first_attempt)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_untagged_enum_after(
|
fn deserialize_untagged_enum_after(
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
variants: &[Variant],
|
variants: &[Variant],
|
||||||
cattrs: &attr::Container,
|
cattrs: &attr::Container,
|
||||||
first_attempt: impl FnOnce(TokenStream) -> Option<Expr>,
|
first_attempt: Option<Expr>,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let deserializer =
|
|
||||||
quote!(_serde::__private::de::ContentRefDeserializer::<__D::Error>::new(&__content));
|
|
||||||
let attempts = variants
|
let attempts = variants
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|variant| !variant.attrs.skip_deserializing())
|
.filter(|variant| !variant.attrs.skip_deserializing())
|
||||||
@@ -1708,12 +1701,10 @@ fn deserialize_untagged_enum_after(
|
|||||||
params,
|
params,
|
||||||
variant,
|
variant,
|
||||||
cattrs,
|
cattrs,
|
||||||
deserializer.clone(),
|
quote!(__deserializer),
|
||||||
))
|
))
|
||||||
});
|
});
|
||||||
let attempts = first_attempt(deserializer.clone())
|
let attempts = first_attempt.into_iter().chain(attempts);
|
||||||
.into_iter()
|
|
||||||
.chain(attempts);
|
|
||||||
// TODO this message could be better by saving the errors from the failed
|
// TODO this message could be better by saving the errors from the failed
|
||||||
// attempts. The heuristic used by TOML was to count the number of fields
|
// attempts. The heuristic used by TOML was to count the number of fields
|
||||||
// processed before an error, and use the error that happened after the
|
// processed before an error, and use the error that happened after the
|
||||||
@@ -1728,6 +1719,7 @@ fn deserialize_untagged_enum_after(
|
|||||||
|
|
||||||
quote_block! {
|
quote_block! {
|
||||||
let __content = try!(<_serde::__private::de::Content as _serde::Deserialize>::deserialize(__deserializer));
|
let __content = try!(<_serde::__private::de::Content as _serde::Deserialize>::deserialize(__deserializer));
|
||||||
|
let __deserializer = _serde::__private::de::ContentRefDeserializer::<__D::Error>::new(&__content);
|
||||||
|
|
||||||
#(
|
#(
|
||||||
if let _serde::__private::Ok(__ok) = #attempts {
|
if let _serde::__private::Ok(__ok) = #attempts {
|
||||||
|
|||||||
Reference in New Issue
Block a user