mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-12 15:31:07 +00:00
Merge pull request #2446 from Mingun/dedup2
Eliminate some duplicated code
This commit is contained in:
+38
-94
@@ -2738,11 +2738,7 @@ where
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
visitor.visit_map(FlatInternallyTaggedAccess {
|
||||
iter: self.0.iter_mut(),
|
||||
pending: None,
|
||||
_marker: PhantomData,
|
||||
})
|
||||
self.deserialize_map(visitor)
|
||||
}
|
||||
|
||||
fn deserialize_enum<V>(
|
||||
@@ -2755,16 +2751,7 @@ where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
for item in self.0.iter_mut() {
|
||||
// items in the vector are nulled out when used. So we can only use
|
||||
// an item if it's still filled in and if the field is one we care
|
||||
// about.
|
||||
let use_item = match *item {
|
||||
None => false,
|
||||
Some((ref c, _)) => c.as_str().map_or(false, |x| variants.contains(&x)),
|
||||
};
|
||||
|
||||
if use_item {
|
||||
let (key, value) = item.take().unwrap();
|
||||
if let Some((key, value)) = use_item(item, variants) {
|
||||
return visitor.visit_enum(EnumDeserializer::new(key, Some(value)));
|
||||
}
|
||||
}
|
||||
@@ -2779,7 +2766,11 @@ where
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
visitor.visit_map(FlatMapAccess::new(self.0.iter()))
|
||||
visitor.visit_map(FlatMapAccess {
|
||||
iter: self.0.iter(),
|
||||
pending_content: None,
|
||||
_marker: PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
fn deserialize_struct<V>(
|
||||
@@ -2791,7 +2782,12 @@ where
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
visitor.visit_map(FlatStructAccess::new(self.0.iter_mut(), fields))
|
||||
visitor.visit_map(FlatStructAccess {
|
||||
iter: self.0.iter_mut(),
|
||||
pending_content: None,
|
||||
fields: fields,
|
||||
_marker: PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
|
||||
@@ -2845,25 +2841,12 @@ where
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
pub struct FlatMapAccess<'a, 'de: 'a, E> {
|
||||
struct FlatMapAccess<'a, 'de: 'a, E> {
|
||||
iter: slice::Iter<'a, Option<(Content<'de>, Content<'de>)>>,
|
||||
pending_content: Option<&'a Content<'de>>,
|
||||
_marker: PhantomData<E>,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<'a, 'de, E> FlatMapAccess<'a, 'de, E> {
|
||||
fn new(
|
||||
iter: slice::Iter<'a, Option<(Content<'de>, Content<'de>)>>,
|
||||
) -> FlatMapAccess<'a, 'de, E> {
|
||||
FlatMapAccess {
|
||||
iter: iter,
|
||||
pending_content: None,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<'a, 'de, E> MapAccess<'de> for FlatMapAccess<'a, 'de, E>
|
||||
where
|
||||
@@ -2878,6 +2861,10 @@ where
|
||||
for item in &mut self.iter {
|
||||
// Items in the vector are nulled out when used by a struct.
|
||||
if let Some((ref key, ref content)) = *item {
|
||||
// Do not take(), instead borrow this entry. The internally tagged
|
||||
// enum does its own buffering so we can't tell whether this entry
|
||||
// is going to be consumed. Borrowing here leaves the entry
|
||||
// available for later flattened fields.
|
||||
self.pending_content = Some(content);
|
||||
return seed.deserialize(ContentRefDeserializer::new(key)).map(Some);
|
||||
}
|
||||
@@ -2897,28 +2884,13 @@ where
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
pub struct FlatStructAccess<'a, 'de: 'a, E> {
|
||||
struct FlatStructAccess<'a, 'de: 'a, E> {
|
||||
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
|
||||
pending_content: Option<Content<'de>>,
|
||||
fields: &'static [&'static str],
|
||||
_marker: PhantomData<E>,
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<'a, 'de, E> FlatStructAccess<'a, 'de, E> {
|
||||
fn new(
|
||||
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
|
||||
fields: &'static [&'static str],
|
||||
) -> FlatStructAccess<'a, 'de, E> {
|
||||
FlatStructAccess {
|
||||
iter: iter,
|
||||
pending_content: None,
|
||||
fields: fields,
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<'a, 'de, E> MapAccess<'de> for FlatStructAccess<'a, 'de, E>
|
||||
where
|
||||
@@ -2931,16 +2903,7 @@ where
|
||||
T: DeserializeSeed<'de>,
|
||||
{
|
||||
while let Some(item) = self.iter.next() {
|
||||
// items in the vector are nulled out when used. So we can only use
|
||||
// an item if it's still filled in and if the field is one we care
|
||||
// about. In case we do not know which fields we want, we take them all.
|
||||
let use_item = match *item {
|
||||
None => false,
|
||||
Some((ref c, _)) => c.as_str().map_or(false, |key| self.fields.contains(&key)),
|
||||
};
|
||||
|
||||
if use_item {
|
||||
let (key, content) = item.take().unwrap();
|
||||
if let Some((key, content)) = use_item(item, self.fields) {
|
||||
self.pending_content = Some(content);
|
||||
return seed.deserialize(ContentDeserializer::new(key)).map(Some);
|
||||
}
|
||||
@@ -2959,44 +2922,25 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if first element of the specified pair matches one of the key from
|
||||
/// `keys` parameter and if this is true, takes it from the option and returns.
|
||||
/// Otherwise, or if `item` already empty, returns `None`.
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
pub struct FlatInternallyTaggedAccess<'a, 'de: 'a, E> {
|
||||
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
|
||||
pending: Option<&'a Content<'de>>,
|
||||
_marker: PhantomData<E>,
|
||||
}
|
||||
fn use_item<'de>(
|
||||
item: &mut Option<(Content<'de>, Content<'de>)>,
|
||||
keys: &[&str],
|
||||
) -> Option<(Content<'de>, Content<'de>)> {
|
||||
// items in the vector are nulled out when used. So we can only use
|
||||
// an item if it's still filled in and if the field is one we care
|
||||
// about.
|
||||
let use_item = match *item {
|
||||
None => false,
|
||||
Some((ref c, _)) => c.as_str().map_or(false, |key| keys.contains(&key)),
|
||||
};
|
||||
|
||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||
impl<'a, 'de, E> MapAccess<'de> for FlatInternallyTaggedAccess<'a, 'de, E>
|
||||
where
|
||||
E: Error,
|
||||
{
|
||||
type Error = E;
|
||||
|
||||
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
|
||||
where
|
||||
T: DeserializeSeed<'de>,
|
||||
{
|
||||
for item in &mut self.iter {
|
||||
if let Some((ref key, ref content)) = *item {
|
||||
// Do not take(), instead borrow this entry. The internally tagged
|
||||
// enum does its own buffering so we can't tell whether this entry
|
||||
// is going to be consumed. Borrowing here leaves the entry
|
||||
// available for later flattened fields.
|
||||
self.pending = Some(content);
|
||||
return seed.deserialize(ContentRefDeserializer::new(key)).map(Some);
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
|
||||
where
|
||||
T: DeserializeSeed<'de>,
|
||||
{
|
||||
match self.pending.take() {
|
||||
Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
|
||||
None => panic!("value is missing"),
|
||||
}
|
||||
if use_item {
|
||||
item.take()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
+22
-29
@@ -3084,23 +3084,29 @@ struct DeTypeGenerics<'a>(&'a Parameters);
|
||||
#[cfg(feature = "deserialize_in_place")]
|
||||
struct InPlaceTypeGenerics<'a>(&'a Parameters);
|
||||
|
||||
/// If `'de` lifetime is defined, prepends it to list of generics
|
||||
/// and then produces tokens for declaration generics on type
|
||||
fn to_tokens(mut generics: syn::Generics, borrowed: &BorrowedLifetimes, tokens: &mut TokenStream) {
|
||||
if borrowed.de_lifetime_param().is_some() {
|
||||
let def = syn::LifetimeParam {
|
||||
attrs: Vec::new(),
|
||||
lifetime: syn::Lifetime::new("'de", Span::call_site()),
|
||||
colon_token: None,
|
||||
bounds: Punctuated::new(),
|
||||
};
|
||||
// Prepend 'de lifetime to list of generics
|
||||
generics.params = Some(syn::GenericParam::Lifetime(def))
|
||||
.into_iter()
|
||||
.chain(generics.params)
|
||||
.collect();
|
||||
}
|
||||
let (_, ty_generics, _) = generics.split_for_impl();
|
||||
ty_generics.to_tokens(tokens);
|
||||
}
|
||||
|
||||
impl<'a> ToTokens for DeTypeGenerics<'a> {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
let mut generics = self.0.generics.clone();
|
||||
if self.0.borrowed.de_lifetime_param().is_some() {
|
||||
let def = syn::LifetimeParam {
|
||||
attrs: Vec::new(),
|
||||
lifetime: syn::Lifetime::new("'de", Span::call_site()),
|
||||
colon_token: None,
|
||||
bounds: Punctuated::new(),
|
||||
};
|
||||
generics.params = Some(syn::GenericParam::Lifetime(def))
|
||||
.into_iter()
|
||||
.chain(generics.params)
|
||||
.collect();
|
||||
}
|
||||
let (_, ty_generics, _) = generics.split_for_impl();
|
||||
ty_generics.to_tokens(tokens);
|
||||
to_tokens(self.0.generics.clone(), &self.0.borrowed, tokens);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3113,20 +3119,7 @@ impl<'a> ToTokens for InPlaceTypeGenerics<'a> {
|
||||
.chain(generics.params)
|
||||
.collect();
|
||||
|
||||
if self.0.borrowed.de_lifetime_param().is_some() {
|
||||
let def = syn::LifetimeParam {
|
||||
attrs: Vec::new(),
|
||||
lifetime: syn::Lifetime::new("'de", Span::call_site()),
|
||||
colon_token: None,
|
||||
bounds: Punctuated::new(),
|
||||
};
|
||||
generics.params = Some(syn::GenericParam::Lifetime(def))
|
||||
.into_iter()
|
||||
.chain(generics.params)
|
||||
.collect();
|
||||
}
|
||||
let (_, ty_generics, _) = generics.split_for_impl();
|
||||
ty_generics.to_tokens(tokens);
|
||||
to_tokens(generics, &self.0.borrowed, tokens);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user