mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-13 00:51:02 +00:00
Merge pull request #2855 from dtolnay/namespan
Produce unreachable_patterns warning when deserialization names collide
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
use crate::fragment::{Expr, Fragment, Match, Stmts};
|
use crate::fragment::{Expr, Fragment, Match, Stmts};
|
||||||
use crate::internals::ast::{Container, Data, Field, Style, Variant};
|
use crate::internals::ast::{Container, Data, Field, Style, Variant};
|
||||||
|
use crate::internals::name::Name;
|
||||||
use crate::internals::{attr, replace_receiver, ungroup, Ctxt, Derive};
|
use crate::internals::{attr, replace_receiver, ungroup, Ctxt, Derive};
|
||||||
use crate::{bound, dummy, pretend, this};
|
use crate::{bound, dummy, pretend, this};
|
||||||
use proc_macro2::{Literal, Span, TokenStream};
|
use proc_macro2::{Literal, Span, TokenStream};
|
||||||
@@ -2002,7 +2003,7 @@ fn deserialize_untagged_newtype_variant(
|
|||||||
|
|
||||||
struct FieldWithAliases<'a> {
|
struct FieldWithAliases<'a> {
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
aliases: &'a BTreeSet<String>,
|
aliases: &'a BTreeSet<Name>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_generated_identifier(
|
fn deserialize_generated_identifier(
|
||||||
@@ -2224,7 +2225,7 @@ fn deserialize_identifier(
|
|||||||
let aliases = field
|
let aliases = field
|
||||||
.aliases
|
.aliases
|
||||||
.iter()
|
.iter()
|
||||||
.map(|alias| Literal::byte_string(alias.as_bytes()));
|
.map(|alias| Literal::byte_string(alias.value.as_bytes()));
|
||||||
quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident))
|
quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::internals::name::{MultiName, Name};
|
||||||
use crate::internals::symbol::*;
|
use crate::internals::symbol::*;
|
||||||
use crate::internals::{ungroup, Ctxt};
|
use crate::internals::{ungroup, Ctxt};
|
||||||
use proc_macro2::{Spacing, Span, TokenStream, TokenTree};
|
use proc_macro2::{Spacing, Span, TokenStream, TokenTree};
|
||||||
@@ -21,7 +22,7 @@ use syn::{parse_quote, token, Ident, Lifetime, Token};
|
|||||||
|
|
||||||
pub use crate::internals::case::RenameRule;
|
pub use crate::internals::case::RenameRule;
|
||||||
|
|
||||||
struct Attr<'c, T> {
|
pub(crate) struct Attr<'c, T> {
|
||||||
cx: &'c Ctxt,
|
cx: &'c Ctxt,
|
||||||
name: Symbol,
|
name: Symbol,
|
||||||
tokens: TokenStream,
|
tokens: TokenStream,
|
||||||
@@ -62,7 +63,7 @@ impl<'c, T> Attr<'c, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get(self) -> Option<T> {
|
pub(crate) fn get(self) -> Option<T> {
|
||||||
self.value
|
self.value
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +91,7 @@ impl<'c> BoolAttr<'c> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VecAttr<'c, T> {
|
pub(crate) struct VecAttr<'c, T> {
|
||||||
cx: &'c Ctxt,
|
cx: &'c Ctxt,
|
||||||
name: Symbol,
|
name: Symbol,
|
||||||
first_dup_tokens: TokenStream,
|
first_dup_tokens: TokenStream,
|
||||||
@@ -125,63 +126,13 @@ impl<'c, T> VecAttr<'c, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get(self) -> Vec<T> {
|
pub(crate) fn get(self) -> Vec<T> {
|
||||||
self.values
|
self.values
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Name {
|
fn unraw(ident: &Ident) -> Ident {
|
||||||
serialize: String,
|
Ident::new(ident.to_string().trim_start_matches("r#"), ident.span())
|
||||||
serialize_renamed: bool,
|
|
||||||
deserialize: String,
|
|
||||||
deserialize_renamed: bool,
|
|
||||||
deserialize_aliases: BTreeSet<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unraw(ident: &Ident) -> String {
|
|
||||||
ident.to_string().trim_start_matches("r#").to_owned()
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Name {
|
|
||||||
fn from_attrs(
|
|
||||||
source_name: String,
|
|
||||||
ser_name: Attr<String>,
|
|
||||||
de_name: Attr<String>,
|
|
||||||
de_aliases: Option<VecAttr<String>>,
|
|
||||||
) -> Name {
|
|
||||||
let mut alias_set = BTreeSet::new();
|
|
||||||
if let Some(de_aliases) = de_aliases {
|
|
||||||
for alias_name in de_aliases.get() {
|
|
||||||
alias_set.insert(alias_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let ser_name = ser_name.get();
|
|
||||||
let ser_renamed = ser_name.is_some();
|
|
||||||
let de_name = de_name.get();
|
|
||||||
let de_renamed = de_name.is_some();
|
|
||||||
Name {
|
|
||||||
serialize: ser_name.unwrap_or_else(|| source_name.clone()),
|
|
||||||
serialize_renamed: ser_renamed,
|
|
||||||
deserialize: de_name.unwrap_or(source_name),
|
|
||||||
deserialize_renamed: de_renamed,
|
|
||||||
deserialize_aliases: alias_set,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the container name for the container when serializing.
|
|
||||||
pub fn serialize_name(&self) -> &str {
|
|
||||||
&self.serialize
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the container name for the container when deserializing.
|
|
||||||
pub fn deserialize_name(&self) -> &str {
|
|
||||||
&self.deserialize
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_aliases(&self) -> &BTreeSet<String> {
|
|
||||||
&self.deserialize_aliases
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
@@ -203,7 +154,7 @@ impl RenameAllRules {
|
|||||||
|
|
||||||
/// Represents struct or enum attribute information.
|
/// Represents struct or enum attribute information.
|
||||||
pub struct Container {
|
pub struct Container {
|
||||||
name: Name,
|
name: MultiName,
|
||||||
transparent: bool,
|
transparent: bool,
|
||||||
deny_unknown_fields: bool,
|
deny_unknown_fields: bool,
|
||||||
default: Default,
|
default: Default,
|
||||||
@@ -327,8 +278,8 @@ impl Container {
|
|||||||
// #[serde(rename = "foo")]
|
// #[serde(rename = "foo")]
|
||||||
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
|
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
|
||||||
let (ser, de) = get_renames(cx, RENAME, &meta)?;
|
let (ser, de) = get_renames(cx, RENAME, &meta)?;
|
||||||
ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
|
ser_name.set_opt(&meta.path, ser.as_ref().map(Name::from));
|
||||||
de_name.set_opt(&meta.path, de.as_ref().map(syn::LitStr::value));
|
de_name.set_opt(&meta.path, de.as_ref().map(Name::from));
|
||||||
} else if meta.path == RENAME_ALL {
|
} else if meta.path == RENAME_ALL {
|
||||||
// #[serde(rename_all = "foo")]
|
// #[serde(rename_all = "foo")]
|
||||||
// #[serde(rename_all(serialize = "foo", deserialize = "bar"))]
|
// #[serde(rename_all(serialize = "foo", deserialize = "bar"))]
|
||||||
@@ -567,7 +518,7 @@ impl Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Container {
|
Container {
|
||||||
name: Name::from_attrs(unraw(&item.ident), ser_name, de_name, None),
|
name: MultiName::from_attrs(Name::from(&unraw(&item.ident)), ser_name, de_name, None),
|
||||||
transparent: transparent.get(),
|
transparent: transparent.get(),
|
||||||
deny_unknown_fields: deny_unknown_fields.get(),
|
deny_unknown_fields: deny_unknown_fields.get(),
|
||||||
default: default.get().unwrap_or(Default::None),
|
default: default.get().unwrap_or(Default::None),
|
||||||
@@ -594,7 +545,7 @@ impl Container {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> &Name {
|
pub fn name(&self) -> &MultiName {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -781,7 +732,7 @@ fn decide_identifier(
|
|||||||
|
|
||||||
/// Represents variant attribute information
|
/// Represents variant attribute information
|
||||||
pub struct Variant {
|
pub struct Variant {
|
||||||
name: Name,
|
name: MultiName,
|
||||||
rename_all_rules: RenameAllRules,
|
rename_all_rules: RenameAllRules,
|
||||||
ser_bound: Option<Vec<syn::WherePredicate>>,
|
ser_bound: Option<Vec<syn::WherePredicate>>,
|
||||||
de_bound: Option<Vec<syn::WherePredicate>>,
|
de_bound: Option<Vec<syn::WherePredicate>>,
|
||||||
@@ -832,15 +783,15 @@ impl Variant {
|
|||||||
// #[serde(rename = "foo")]
|
// #[serde(rename = "foo")]
|
||||||
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
|
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
|
||||||
let (ser, de) = get_multiple_renames(cx, &meta)?;
|
let (ser, de) = get_multiple_renames(cx, &meta)?;
|
||||||
ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
|
ser_name.set_opt(&meta.path, ser.as_ref().map(Name::from));
|
||||||
for de_value in de {
|
for de_value in de {
|
||||||
de_name.set_if_none(de_value.value());
|
de_name.set_if_none(Name::from(&de_value));
|
||||||
de_aliases.insert(&meta.path, de_value.value());
|
de_aliases.insert(&meta.path, Name::from(&de_value));
|
||||||
}
|
}
|
||||||
} else if meta.path == ALIAS {
|
} else if meta.path == ALIAS {
|
||||||
// #[serde(alias = "foo")]
|
// #[serde(alias = "foo")]
|
||||||
if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
|
if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
|
||||||
de_aliases.insert(&meta.path, s.value());
|
de_aliases.insert(&meta.path, Name::from(&s));
|
||||||
}
|
}
|
||||||
} else if meta.path == RENAME_ALL {
|
} else if meta.path == RENAME_ALL {
|
||||||
// #[serde(rename_all = "foo")]
|
// #[serde(rename_all = "foo")]
|
||||||
@@ -947,7 +898,12 @@ impl Variant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Variant {
|
Variant {
|
||||||
name: Name::from_attrs(unraw(&variant.ident), ser_name, de_name, Some(de_aliases)),
|
name: MultiName::from_attrs(
|
||||||
|
Name::from(&unraw(&variant.ident)),
|
||||||
|
ser_name,
|
||||||
|
de_name,
|
||||||
|
Some(de_aliases),
|
||||||
|
),
|
||||||
rename_all_rules: RenameAllRules {
|
rename_all_rules: RenameAllRules {
|
||||||
serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
|
serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
|
||||||
deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None),
|
deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None),
|
||||||
@@ -964,20 +920,23 @@ impl Variant {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> &Name {
|
pub fn name(&self) -> &MultiName {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aliases(&self) -> &BTreeSet<String> {
|
pub fn aliases(&self) -> &BTreeSet<Name> {
|
||||||
self.name.deserialize_aliases()
|
self.name.deserialize_aliases()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rename_by_rules(&mut self, rules: RenameAllRules) {
|
pub fn rename_by_rules(&mut self, rules: RenameAllRules) {
|
||||||
if !self.name.serialize_renamed {
|
if !self.name.serialize_renamed {
|
||||||
self.name.serialize = rules.serialize.apply_to_variant(&self.name.serialize);
|
self.name.serialize.value =
|
||||||
|
rules.serialize.apply_to_variant(&self.name.serialize.value);
|
||||||
}
|
}
|
||||||
if !self.name.deserialize_renamed {
|
if !self.name.deserialize_renamed {
|
||||||
self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize);
|
self.name.deserialize.value = rules
|
||||||
|
.deserialize
|
||||||
|
.apply_to_variant(&self.name.deserialize.value);
|
||||||
}
|
}
|
||||||
self.name
|
self.name
|
||||||
.deserialize_aliases
|
.deserialize_aliases
|
||||||
@@ -1023,7 +982,7 @@ impl Variant {
|
|||||||
|
|
||||||
/// Represents field attribute information
|
/// Represents field attribute information
|
||||||
pub struct Field {
|
pub struct Field {
|
||||||
name: Name,
|
name: MultiName,
|
||||||
skip_serializing: bool,
|
skip_serializing: bool,
|
||||||
skip_deserializing: bool,
|
skip_deserializing: bool,
|
||||||
skip_serializing_if: Option<syn::ExprPath>,
|
skip_serializing_if: Option<syn::ExprPath>,
|
||||||
@@ -1082,8 +1041,11 @@ impl Field {
|
|||||||
let mut flatten = BoolAttr::none(cx, FLATTEN);
|
let mut flatten = BoolAttr::none(cx, FLATTEN);
|
||||||
|
|
||||||
let ident = match &field.ident {
|
let ident = match &field.ident {
|
||||||
Some(ident) => unraw(ident),
|
Some(ident) => Name::from(&unraw(ident)),
|
||||||
None => index.to_string(),
|
None => Name {
|
||||||
|
value: index.to_string(),
|
||||||
|
span: Span::call_site(),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(borrow_attribute) = attrs.and_then(|variant| variant.borrow.as_ref()) {
|
if let Some(borrow_attribute) = attrs.and_then(|variant| variant.borrow.as_ref()) {
|
||||||
@@ -1119,15 +1081,15 @@ impl Field {
|
|||||||
// #[serde(rename = "foo")]
|
// #[serde(rename = "foo")]
|
||||||
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
|
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
|
||||||
let (ser, de) = get_multiple_renames(cx, &meta)?;
|
let (ser, de) = get_multiple_renames(cx, &meta)?;
|
||||||
ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
|
ser_name.set_opt(&meta.path, ser.as_ref().map(Name::from));
|
||||||
for de_value in de {
|
for de_value in de {
|
||||||
de_name.set_if_none(de_value.value());
|
de_name.set_if_none(Name::from(&de_value));
|
||||||
de_aliases.insert(&meta.path, de_value.value());
|
de_aliases.insert(&meta.path, Name::from(&de_value));
|
||||||
}
|
}
|
||||||
} else if meta.path == ALIAS {
|
} else if meta.path == ALIAS {
|
||||||
// #[serde(alias = "foo")]
|
// #[serde(alias = "foo")]
|
||||||
if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
|
if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
|
||||||
de_aliases.insert(&meta.path, s.value());
|
de_aliases.insert(&meta.path, Name::from(&s));
|
||||||
}
|
}
|
||||||
} else if meta.path == DEFAULT {
|
} else if meta.path == DEFAULT {
|
||||||
if meta.input.peek(Token![=]) {
|
if meta.input.peek(Token![=]) {
|
||||||
@@ -1290,7 +1252,7 @@ impl Field {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Field {
|
Field {
|
||||||
name: Name::from_attrs(ident, ser_name, de_name, Some(de_aliases)),
|
name: MultiName::from_attrs(ident, ser_name, de_name, Some(de_aliases)),
|
||||||
skip_serializing: skip_serializing.get(),
|
skip_serializing: skip_serializing.get(),
|
||||||
skip_deserializing: skip_deserializing.get(),
|
skip_deserializing: skip_deserializing.get(),
|
||||||
skip_serializing_if: skip_serializing_if.get(),
|
skip_serializing_if: skip_serializing_if.get(),
|
||||||
@@ -1306,20 +1268,22 @@ impl Field {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> &Name {
|
pub fn name(&self) -> &MultiName {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aliases(&self) -> &BTreeSet<String> {
|
pub fn aliases(&self) -> &BTreeSet<Name> {
|
||||||
self.name.deserialize_aliases()
|
self.name.deserialize_aliases()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rename_by_rules(&mut self, rules: RenameAllRules) {
|
pub fn rename_by_rules(&mut self, rules: RenameAllRules) {
|
||||||
if !self.name.serialize_renamed {
|
if !self.name.serialize_renamed {
|
||||||
self.name.serialize = rules.serialize.apply_to_field(&self.name.serialize);
|
self.name.serialize.value = rules.serialize.apply_to_field(&self.name.serialize.value);
|
||||||
}
|
}
|
||||||
if !self.name.deserialize_renamed {
|
if !self.name.deserialize_renamed {
|
||||||
self.name.deserialize = rules.deserialize.apply_to_field(&self.name.deserialize);
|
self.name.deserialize.value = rules
|
||||||
|
.deserialize
|
||||||
|
.apply_to_field(&self.name.deserialize.value);
|
||||||
}
|
}
|
||||||
self.name
|
self.name
|
||||||
.deserialize_aliases
|
.deserialize_aliases
|
||||||
@@ -1769,7 +1733,7 @@ fn is_primitive_path(path: &syn::Path, primitive: &str) -> bool {
|
|||||||
// attribute on the field so there must be at least one borrowable lifetime.
|
// attribute on the field so there must be at least one borrowable lifetime.
|
||||||
fn borrowable_lifetimes(
|
fn borrowable_lifetimes(
|
||||||
cx: &Ctxt,
|
cx: &Ctxt,
|
||||||
name: &str,
|
name: &Name,
|
||||||
field: &syn::Field,
|
field: &syn::Field,
|
||||||
) -> Result<BTreeSet<syn::Lifetime>, ()> {
|
) -> Result<BTreeSet<syn::Lifetime>, ()> {
|
||||||
let mut lifetimes = BTreeSet::new();
|
let mut lifetimes = BTreeSet::new();
|
||||||
|
|||||||
@@ -332,13 +332,13 @@ fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
|
|||||||
let name = field.attrs.name();
|
let name = field.attrs.name();
|
||||||
let ser_name = name.serialize_name();
|
let ser_name = name.serialize_name();
|
||||||
|
|
||||||
if check_ser && ser_name == tag {
|
if check_ser && ser_name.value == tag {
|
||||||
diagnose_conflict();
|
diagnose_conflict();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for de_name in field.attrs.aliases() {
|
for de_name in field.attrs.aliases() {
|
||||||
if check_de && de_name == tag {
|
if check_de && de_name.value == tag {
|
||||||
diagnose_conflict();
|
diagnose_conflict();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
pub mod ast;
|
pub mod ast;
|
||||||
pub mod attr;
|
pub mod attr;
|
||||||
|
pub mod name;
|
||||||
|
|
||||||
mod case;
|
mod case;
|
||||||
mod check;
|
mod check;
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
use crate::internals::attr::{Attr, VecAttr};
|
||||||
|
use proc_macro2::{Ident, Span, TokenStream};
|
||||||
|
use quote::ToTokens;
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
use std::collections::BTreeSet;
|
||||||
|
use std::fmt::{self, Display};
|
||||||
|
use syn::LitStr;
|
||||||
|
|
||||||
|
pub struct MultiName {
|
||||||
|
pub(crate) serialize: Name,
|
||||||
|
pub(crate) serialize_renamed: bool,
|
||||||
|
pub(crate) deserialize: Name,
|
||||||
|
pub(crate) deserialize_renamed: bool,
|
||||||
|
pub(crate) deserialize_aliases: BTreeSet<Name>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MultiName {
|
||||||
|
pub(crate) fn from_attrs(
|
||||||
|
source_name: Name,
|
||||||
|
ser_name: Attr<Name>,
|
||||||
|
de_name: Attr<Name>,
|
||||||
|
de_aliases: Option<VecAttr<Name>>,
|
||||||
|
) -> Self {
|
||||||
|
let mut alias_set = BTreeSet::new();
|
||||||
|
if let Some(de_aliases) = de_aliases {
|
||||||
|
for alias_name in de_aliases.get() {
|
||||||
|
alias_set.insert(alias_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let ser_name = ser_name.get();
|
||||||
|
let ser_renamed = ser_name.is_some();
|
||||||
|
let de_name = de_name.get();
|
||||||
|
let de_renamed = de_name.is_some();
|
||||||
|
MultiName {
|
||||||
|
serialize: ser_name.unwrap_or_else(|| source_name.clone()),
|
||||||
|
serialize_renamed: ser_renamed,
|
||||||
|
deserialize: de_name.unwrap_or(source_name),
|
||||||
|
deserialize_renamed: de_renamed,
|
||||||
|
deserialize_aliases: alias_set,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the container name for the container when serializing.
|
||||||
|
pub fn serialize_name(&self) -> &Name {
|
||||||
|
&self.serialize
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the container name for the container when deserializing.
|
||||||
|
pub fn deserialize_name(&self) -> &Name {
|
||||||
|
&self.deserialize
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn deserialize_aliases(&self) -> &BTreeSet<Name> {
|
||||||
|
&self.deserialize_aliases
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Name {
|
||||||
|
pub value: String,
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToTokens for Name {
|
||||||
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
|
LitStr::new(&self.value, self.span).to_tokens(tokens);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for Name {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
Ord::cmp(&self.value, &other.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Name {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(Ord::cmp(self, other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for Name {}
|
||||||
|
|
||||||
|
impl PartialEq for Name {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.value == other.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Ident> for Name {
|
||||||
|
fn from(ident: &Ident) -> Self {
|
||||||
|
Name {
|
||||||
|
value: ident.to_string(),
|
||||||
|
span: ident.span(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&LitStr> for Name {
|
||||||
|
fn from(lit: &LitStr) -> Self {
|
||||||
|
Name {
|
||||||
|
value: lit.value(),
|
||||||
|
span: lit.span(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Name {
|
||||||
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
Display::fmt(&self.value, formatter)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::fragment::{Fragment, Match, Stmts};
|
use crate::fragment::{Fragment, Match, Stmts};
|
||||||
use crate::internals::ast::{Container, Data, Field, Style, Variant};
|
use crate::internals::ast::{Container, Data, Field, Style, Variant};
|
||||||
|
use crate::internals::name::Name;
|
||||||
use crate::internals::{attr, replace_receiver, Ctxt, Derive};
|
use crate::internals::{attr, replace_receiver, Ctxt, Derive};
|
||||||
use crate::{bound, dummy, pretend, this};
|
use crate::{bound, dummy, pretend, this};
|
||||||
use proc_macro2::{Span, TokenStream};
|
use proc_macro2::{Span, TokenStream};
|
||||||
@@ -798,9 +799,9 @@ fn serialize_untagged_variant(
|
|||||||
|
|
||||||
enum TupleVariant<'a> {
|
enum TupleVariant<'a> {
|
||||||
ExternallyTagged {
|
ExternallyTagged {
|
||||||
type_name: &'a str,
|
type_name: &'a Name,
|
||||||
variant_index: u32,
|
variant_index: u32,
|
||||||
variant_name: &'a str,
|
variant_name: &'a Name,
|
||||||
},
|
},
|
||||||
Untagged,
|
Untagged,
|
||||||
}
|
}
|
||||||
@@ -867,11 +868,11 @@ fn serialize_tuple_variant(
|
|||||||
enum StructVariant<'a> {
|
enum StructVariant<'a> {
|
||||||
ExternallyTagged {
|
ExternallyTagged {
|
||||||
variant_index: u32,
|
variant_index: u32,
|
||||||
variant_name: &'a str,
|
variant_name: &'a Name,
|
||||||
},
|
},
|
||||||
InternallyTagged {
|
InternallyTagged {
|
||||||
tag: &'a str,
|
tag: &'a str,
|
||||||
variant_name: &'a str,
|
variant_name: &'a Name,
|
||||||
},
|
},
|
||||||
Untagged,
|
Untagged,
|
||||||
}
|
}
|
||||||
@@ -880,7 +881,7 @@ fn serialize_struct_variant(
|
|||||||
context: StructVariant,
|
context: StructVariant,
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
name: &str,
|
name: &Name,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
if fields.iter().any(|field| field.attrs.flatten()) {
|
if fields.iter().any(|field| field.attrs.flatten()) {
|
||||||
return serialize_struct_variant_with_flatten(context, params, fields, name);
|
return serialize_struct_variant_with_flatten(context, params, fields, name);
|
||||||
@@ -964,7 +965,7 @@ fn serialize_struct_variant_with_flatten(
|
|||||||
context: StructVariant,
|
context: StructVariant,
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
name: &str,
|
name: &Name,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let struct_trait = StructTrait::SerializeMap;
|
let struct_trait = StructTrait::SerializeMap;
|
||||||
let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait);
|
let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait);
|
||||||
|
|||||||
Reference in New Issue
Block a user