Skip to content

Commit 373edcd

Browse files
committed
Keep track of a span for alias strings
1 parent f0b5c4f commit 373edcd

File tree

6 files changed

+121
-45
lines changed

6 files changed

+121
-45
lines changed

serde_derive/src/de.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::fragment::{Expr, Fragment, Match, Stmts};
22
use crate::internals::ast::{Container, Data, Field, Style, Variant};
3+
use crate::internals::name::Name;
34
use crate::internals::{attr, replace_receiver, ungroup, Ctxt, Derive};
45
use crate::{bound, dummy, pretend, this};
56
use proc_macro2::{Literal, Span, TokenStream};
@@ -2002,7 +2003,7 @@ fn deserialize_untagged_newtype_variant(
20022003

20032004
struct FieldWithAliases<'a> {
20042005
ident: Ident,
2005-
aliases: &'a BTreeSet<String>,
2006+
aliases: &'a BTreeSet<Name>,
20062007
}
20072008

20082009
fn deserialize_generated_identifier(
@@ -2224,7 +2225,7 @@ fn deserialize_identifier(
22242225
let aliases = field
22252226
.aliases
22262227
.iter()
2227-
.map(|alias| Literal::byte_string(alias.as_bytes()));
2228+
.map(|alias| Literal::byte_string(alias.value.as_bytes()));
22282229
quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident))
22292230
});
22302231

serde_derive/src/internals/attr.rs

+37-24
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::internals::name::MultiName;
1+
use crate::internals::name::{MultiName, Name};
22
use crate::internals::symbol::*;
33
use crate::internals::{ungroup, Ctxt};
44
use proc_macro2::{Spacing, Span, TokenStream, TokenTree};
@@ -131,8 +131,8 @@ impl<'c, T> VecAttr<'c, T> {
131131
}
132132
}
133133

134-
fn unraw(ident: &Ident) -> String {
135-
ident.to_string().trim_start_matches("r#").to_owned()
134+
fn unraw(ident: &Ident) -> Ident {
135+
Ident::new(ident.to_string().trim_start_matches("r#"), ident.span())
136136
}
137137

138138
#[derive(Copy, Clone)]
@@ -278,8 +278,8 @@ impl Container {
278278
// #[serde(rename = "foo")]
279279
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
280280
let (ser, de) = get_renames(cx, RENAME, &meta)?;
281-
ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
282-
de_name.set_opt(&meta.path, de.as_ref().map(syn::LitStr::value));
281+
ser_name.set_opt(&meta.path, ser.as_ref().map(Name::from));
282+
de_name.set_opt(&meta.path, de.as_ref().map(Name::from));
283283
} else if meta.path == RENAME_ALL {
284284
// #[serde(rename_all = "foo")]
285285
// #[serde(rename_all(serialize = "foo", deserialize = "bar"))]
@@ -518,7 +518,7 @@ impl Container {
518518
}
519519

520520
Container {
521-
name: MultiName::from_attrs(unraw(&item.ident), ser_name, de_name, None),
521+
name: MultiName::from_attrs(Name::from(&unraw(&item.ident)), ser_name, de_name, None),
522522
transparent: transparent.get(),
523523
deny_unknown_fields: deny_unknown_fields.get(),
524524
default: default.get().unwrap_or(Default::None),
@@ -783,15 +783,15 @@ impl Variant {
783783
// #[serde(rename = "foo")]
784784
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
785785
let (ser, de) = get_multiple_renames(cx, &meta)?;
786-
ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
786+
ser_name.set_opt(&meta.path, ser.as_ref().map(Name::from));
787787
for de_value in de {
788-
de_name.set_if_none(de_value.value());
789-
de_aliases.insert(&meta.path, de_value.value());
788+
de_name.set_if_none(Name::from(&de_value));
789+
de_aliases.insert(&meta.path, Name::from(&de_value));
790790
}
791791
} else if meta.path == ALIAS {
792792
// #[serde(alias = "foo")]
793793
if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
794-
de_aliases.insert(&meta.path, s.value());
794+
de_aliases.insert(&meta.path, Name::from(&s));
795795
}
796796
} else if meta.path == RENAME_ALL {
797797
// #[serde(rename_all = "foo")]
@@ -898,7 +898,12 @@ impl Variant {
898898
}
899899

900900
Variant {
901-
name: MultiName::from_attrs(unraw(&variant.ident), ser_name, de_name, Some(de_aliases)),
901+
name: MultiName::from_attrs(
902+
Name::from(&unraw(&variant.ident)),
903+
ser_name,
904+
de_name,
905+
Some(de_aliases),
906+
),
902907
rename_all_rules: RenameAllRules {
903908
serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
904909
deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None),
@@ -919,16 +924,19 @@ impl Variant {
919924
&self.name
920925
}
921926

922-
pub fn aliases(&self) -> &BTreeSet<String> {
927+
pub fn aliases(&self) -> &BTreeSet<Name> {
923928
self.name.deserialize_aliases()
924929
}
925930

926931
pub fn rename_by_rules(&mut self, rules: RenameAllRules) {
927932
if !self.name.serialize_renamed {
928-
self.name.serialize = rules.serialize.apply_to_variant(&self.name.serialize);
933+
self.name.serialize.value =
934+
rules.serialize.apply_to_variant(&self.name.serialize.value);
929935
}
930936
if !self.name.deserialize_renamed {
931-
self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize);
937+
self.name.deserialize.value = rules
938+
.deserialize
939+
.apply_to_variant(&self.name.deserialize.value);
932940
}
933941
self.name
934942
.deserialize_aliases
@@ -1033,8 +1041,11 @@ impl Field {
10331041
let mut flatten = BoolAttr::none(cx, FLATTEN);
10341042

10351043
let ident = match &field.ident {
1036-
Some(ident) => unraw(ident),
1037-
None => index.to_string(),
1044+
Some(ident) => Name::from(&unraw(ident)),
1045+
None => Name {
1046+
value: index.to_string(),
1047+
span: Span::call_site(),
1048+
},
10381049
};
10391050

10401051
if let Some(borrow_attribute) = attrs.and_then(|variant| variant.borrow.as_ref()) {
@@ -1070,15 +1081,15 @@ impl Field {
10701081
// #[serde(rename = "foo")]
10711082
// #[serde(rename(serialize = "foo", deserialize = "bar"))]
10721083
let (ser, de) = get_multiple_renames(cx, &meta)?;
1073-
ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
1084+
ser_name.set_opt(&meta.path, ser.as_ref().map(Name::from));
10741085
for de_value in de {
1075-
de_name.set_if_none(de_value.value());
1076-
de_aliases.insert(&meta.path, de_value.value());
1086+
de_name.set_if_none(Name::from(&de_value));
1087+
de_aliases.insert(&meta.path, Name::from(&de_value));
10771088
}
10781089
} else if meta.path == ALIAS {
10791090
// #[serde(alias = "foo")]
10801091
if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
1081-
de_aliases.insert(&meta.path, s.value());
1092+
de_aliases.insert(&meta.path, Name::from(&s));
10821093
}
10831094
} else if meta.path == DEFAULT {
10841095
if meta.input.peek(Token![=]) {
@@ -1261,16 +1272,18 @@ impl Field {
12611272
&self.name
12621273
}
12631274

1264-
pub fn aliases(&self) -> &BTreeSet<String> {
1275+
pub fn aliases(&self) -> &BTreeSet<Name> {
12651276
self.name.deserialize_aliases()
12661277
}
12671278

12681279
pub fn rename_by_rules(&mut self, rules: RenameAllRules) {
12691280
if !self.name.serialize_renamed {
1270-
self.name.serialize = rules.serialize.apply_to_field(&self.name.serialize);
1281+
self.name.serialize.value = rules.serialize.apply_to_field(&self.name.serialize.value);
12711282
}
12721283
if !self.name.deserialize_renamed {
1273-
self.name.deserialize = rules.deserialize.apply_to_field(&self.name.deserialize);
1284+
self.name.deserialize.value = rules
1285+
.deserialize
1286+
.apply_to_field(&self.name.deserialize.value);
12741287
}
12751288
self.name
12761289
.deserialize_aliases
@@ -1720,7 +1733,7 @@ fn is_primitive_path(path: &syn::Path, primitive: &str) -> bool {
17201733
// attribute on the field so there must be at least one borrowable lifetime.
17211734
fn borrowable_lifetimes(
17221735
cx: &Ctxt,
1723-
name: &str,
1736+
name: &Name,
17241737
field: &syn::Field,
17251738
) -> Result<BTreeSet<syn::Lifetime>, ()> {
17261739
let mut lifetimes = BTreeSet::new();

serde_derive/src/internals/check.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -332,13 +332,13 @@ fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
332332
let name = field.attrs.name();
333333
let ser_name = name.serialize_name();
334334

335-
if check_ser && ser_name == tag {
335+
if check_ser && ser_name.value == tag {
336336
diagnose_conflict();
337337
return;
338338
}
339339

340340
for de_name in field.attrs.aliases() {
341-
if check_de && de_name == tag {
341+
if check_de && de_name.value == tag {
342342
diagnose_conflict();
343343
return;
344344
}

serde_derive/src/internals/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
pub mod ast;
22
pub mod attr;
3+
pub mod name;
34

45
mod case;
56
mod check;
67
mod ctxt;
7-
mod name;
88
mod receiver;
99
mod respan;
1010
mod symbol;

serde_derive/src/internals/name.rs

+71-10
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
use crate::internals::attr::{Attr, VecAttr};
2+
use proc_macro2::{Ident, Span, TokenStream};
3+
use quote::ToTokens;
4+
use std::cmp::Ordering;
25
use std::collections::BTreeSet;
6+
use std::fmt::{self, Display};
7+
use syn::LitStr;
38

49
pub struct MultiName {
5-
pub(crate) serialize: String,
10+
pub(crate) serialize: Name,
611
pub(crate) serialize_renamed: bool,
7-
pub(crate) deserialize: String,
12+
pub(crate) deserialize: Name,
813
pub(crate) deserialize_renamed: bool,
9-
pub(crate) deserialize_aliases: BTreeSet<String>,
14+
pub(crate) deserialize_aliases: BTreeSet<Name>,
1015
}
1116

1217
impl MultiName {
1318
pub(crate) fn from_attrs(
14-
source_name: String,
15-
ser_name: Attr<String>,
16-
de_name: Attr<String>,
17-
de_aliases: Option<VecAttr<String>>,
19+
source_name: Name,
20+
ser_name: Attr<Name>,
21+
de_name: Attr<Name>,
22+
de_aliases: Option<VecAttr<Name>>,
1823
) -> Self {
1924
let mut alias_set = BTreeSet::new();
2025
if let Some(de_aliases) = de_aliases {
@@ -37,16 +42,72 @@ impl MultiName {
3742
}
3843

3944
/// Return the container name for the container when serializing.
40-
pub fn serialize_name(&self) -> &str {
45+
pub fn serialize_name(&self) -> &Name {
4146
&self.serialize
4247
}
4348

4449
/// Return the container name for the container when deserializing.
45-
pub fn deserialize_name(&self) -> &str {
50+
pub fn deserialize_name(&self) -> &Name {
4651
&self.deserialize
4752
}
4853

49-
pub(crate) fn deserialize_aliases(&self) -> &BTreeSet<String> {
54+
pub(crate) fn deserialize_aliases(&self) -> &BTreeSet<Name> {
5055
&self.deserialize_aliases
5156
}
5257
}
58+
59+
#[derive(Clone)]
60+
pub struct Name {
61+
pub value: String,
62+
pub span: Span,
63+
}
64+
65+
impl ToTokens for Name {
66+
fn to_tokens(&self, tokens: &mut TokenStream) {
67+
LitStr::new(&self.value, self.span).to_tokens(tokens);
68+
}
69+
}
70+
71+
impl Ord for Name {
72+
fn cmp(&self, other: &Self) -> Ordering {
73+
Ord::cmp(&self.value, &other.value)
74+
}
75+
}
76+
77+
impl PartialOrd for Name {
78+
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
79+
Some(Ord::cmp(self, other))
80+
}
81+
}
82+
83+
impl Eq for Name {}
84+
85+
impl PartialEq for Name {
86+
fn eq(&self, other: &Self) -> bool {
87+
self.value == other.value
88+
}
89+
}
90+
91+
impl From<&Ident> for Name {
92+
fn from(ident: &Ident) -> Self {
93+
Name {
94+
value: ident.to_string(),
95+
span: ident.span(),
96+
}
97+
}
98+
}
99+
100+
impl From<&LitStr> for Name {
101+
fn from(lit: &LitStr) -> Self {
102+
Name {
103+
value: lit.value(),
104+
span: lit.span(),
105+
}
106+
}
107+
}
108+
109+
impl Display for Name {
110+
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
111+
Display::fmt(&self.value, formatter)
112+
}
113+
}

serde_derive/src/ser.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::fragment::{Fragment, Match, Stmts};
22
use crate::internals::ast::{Container, Data, Field, Style, Variant};
3+
use crate::internals::name::Name;
34
use crate::internals::{attr, replace_receiver, Ctxt, Derive};
45
use crate::{bound, dummy, pretend, this};
56
use proc_macro2::{Span, TokenStream};
@@ -798,9 +799,9 @@ fn serialize_untagged_variant(
798799

799800
enum TupleVariant<'a> {
800801
ExternallyTagged {
801-
type_name: &'a str,
802+
type_name: &'a Name,
802803
variant_index: u32,
803-
variant_name: &'a str,
804+
variant_name: &'a Name,
804805
},
805806
Untagged,
806807
}
@@ -867,11 +868,11 @@ fn serialize_tuple_variant(
867868
enum StructVariant<'a> {
868869
ExternallyTagged {
869870
variant_index: u32,
870-
variant_name: &'a str,
871+
variant_name: &'a Name,
871872
},
872873
InternallyTagged {
873874
tag: &'a str,
874-
variant_name: &'a str,
875+
variant_name: &'a Name,
875876
},
876877
Untagged,
877878
}
@@ -880,7 +881,7 @@ fn serialize_struct_variant(
880881
context: StructVariant,
881882
params: &Parameters,
882883
fields: &[Field],
883-
name: &str,
884+
name: &Name,
884885
) -> Fragment {
885886
if fields.iter().any(|field| field.attrs.flatten()) {
886887
return serialize_struct_variant_with_flatten(context, params, fields, name);
@@ -964,7 +965,7 @@ fn serialize_struct_variant_with_flatten(
964965
context: StructVariant,
965966
params: &Parameters,
966967
fields: &[Field],
967-
name: &str,
968+
name: &Name,
968969
) -> Fragment {
969970
let struct_trait = StructTrait::SerializeMap;
970971
let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait);

0 commit comments

Comments
 (0)