1 use internals::symbol::*;
2 use internals::{ungroup, Ctxt};
3 use proc_macro2::{Spacing, Span, TokenStream, TokenTree};
4 use quote::ToTokens;
5 use std::borrow::Cow;
6 use std::collections::BTreeSet;
7 use std::iter::FromIterator;
8 use syn;
9 use syn::meta::ParseNestedMeta;
10 use syn::parse::ParseStream;
11 use syn::punctuated::Punctuated;
12 use syn::{token, Ident, Lifetime};
13
14 // This module handles parsing of `#[serde(...)]` attributes. The entrypoints
15 // are `attr::Container::from_ast`, `attr::Variant::from_ast`, and
16 // `attr::Field::from_ast`. Each returns an instance of the corresponding
17 // struct. Note that none of them return a Result. Unrecognized, malformed, or
18 // duplicated attributes result in a span_err but otherwise are ignored. The
19 // user will see errors simultaneously for all bad attributes in the crate
20 // rather than just the first.
21
22 pub use internals::case::RenameRule;
23
24 struct Attr<'c, T> {
25 cx: &'c Ctxt,
26 name: Symbol,
27 tokens: TokenStream,
28 value: Option<T>,
29 }
30
31 impl<'c, T> Attr<'c, T> {
none(cx: &'c Ctxt, name: Symbol) -> Self32 fn none(cx: &'c Ctxt, name: Symbol) -> Self {
33 Attr {
34 cx,
35 name,
36 tokens: TokenStream::new(),
37 value: None,
38 }
39 }
40
set<A: ToTokens>(&mut self, obj: A, value: T)41 fn set<A: ToTokens>(&mut self, obj: A, value: T) {
42 let tokens = obj.into_token_stream();
43
44 if self.value.is_some() {
45 let msg = format!("duplicate serde attribute `{}`", self.name);
46 self.cx.error_spanned_by(tokens, msg);
47 } else {
48 self.tokens = tokens;
49 self.value = Some(value);
50 }
51 }
52
set_opt<A: ToTokens>(&mut self, obj: A, value: Option<T>)53 fn set_opt<A: ToTokens>(&mut self, obj: A, value: Option<T>) {
54 if let Some(value) = value {
55 self.set(obj, value);
56 }
57 }
58
set_if_none(&mut self, value: T)59 fn set_if_none(&mut self, value: T) {
60 if self.value.is_none() {
61 self.value = Some(value);
62 }
63 }
64
get(self) -> Option<T>65 fn get(self) -> Option<T> {
66 self.value
67 }
68
get_with_tokens(self) -> Option<(TokenStream, T)>69 fn get_with_tokens(self) -> Option<(TokenStream, T)> {
70 match self.value {
71 Some(v) => Some((self.tokens, v)),
72 None => None,
73 }
74 }
75 }
76
77 struct BoolAttr<'c>(Attr<'c, ()>);
78
79 impl<'c> BoolAttr<'c> {
none(cx: &'c Ctxt, name: Symbol) -> Self80 fn none(cx: &'c Ctxt, name: Symbol) -> Self {
81 BoolAttr(Attr::none(cx, name))
82 }
83
set_true<A: ToTokens>(&mut self, obj: A)84 fn set_true<A: ToTokens>(&mut self, obj: A) {
85 self.0.set(obj, ());
86 }
87
get(&self) -> bool88 fn get(&self) -> bool {
89 self.0.value.is_some()
90 }
91 }
92
93 struct VecAttr<'c, T> {
94 cx: &'c Ctxt,
95 name: Symbol,
96 first_dup_tokens: TokenStream,
97 values: Vec<T>,
98 }
99
100 impl<'c, T> VecAttr<'c, T> {
none(cx: &'c Ctxt, name: Symbol) -> Self101 fn none(cx: &'c Ctxt, name: Symbol) -> Self {
102 VecAttr {
103 cx,
104 name,
105 first_dup_tokens: TokenStream::new(),
106 values: Vec::new(),
107 }
108 }
109
insert<A: ToTokens>(&mut self, obj: A, value: T)110 fn insert<A: ToTokens>(&mut self, obj: A, value: T) {
111 if self.values.len() == 1 {
112 self.first_dup_tokens = obj.into_token_stream();
113 }
114 self.values.push(value);
115 }
116
at_most_one(mut self) -> Option<T>117 fn at_most_one(mut self) -> Option<T> {
118 if self.values.len() > 1 {
119 let dup_token = self.first_dup_tokens;
120 let msg = format!("duplicate serde attribute `{}`", self.name);
121 self.cx.error_spanned_by(dup_token, msg);
122 None
123 } else {
124 self.values.pop()
125 }
126 }
127
get(self) -> Vec<T>128 fn get(self) -> Vec<T> {
129 self.values
130 }
131 }
132
133 pub struct Name {
134 serialize: String,
135 serialize_renamed: bool,
136 deserialize: String,
137 deserialize_renamed: bool,
138 deserialize_aliases: Vec<String>,
139 }
140
unraw(ident: &Ident) -> String141 fn unraw(ident: &Ident) -> String {
142 ident.to_string().trim_start_matches("r#").to_owned()
143 }
144
145 impl Name {
from_attrs( source_name: String, ser_name: Attr<String>, de_name: Attr<String>, de_aliases: Option<VecAttr<String>>, ) -> Name146 fn from_attrs(
147 source_name: String,
148 ser_name: Attr<String>,
149 de_name: Attr<String>,
150 de_aliases: Option<VecAttr<String>>,
151 ) -> Name {
152 let deserialize_aliases = match de_aliases {
153 Some(de_aliases) => {
154 let mut alias_list = BTreeSet::new();
155 for alias_name in de_aliases.get() {
156 alias_list.insert(alias_name);
157 }
158 alias_list.into_iter().collect()
159 }
160 None => Vec::new(),
161 };
162
163 let ser_name = ser_name.get();
164 let ser_renamed = ser_name.is_some();
165 let de_name = de_name.get();
166 let de_renamed = de_name.is_some();
167 Name {
168 serialize: ser_name.unwrap_or_else(|| source_name.clone()),
169 serialize_renamed: ser_renamed,
170 deserialize: de_name.unwrap_or(source_name),
171 deserialize_renamed: de_renamed,
172 deserialize_aliases,
173 }
174 }
175
176 /// Return the container name for the container when serializing.
serialize_name(&self) -> String177 pub fn serialize_name(&self) -> String {
178 self.serialize.clone()
179 }
180
181 /// Return the container name for the container when deserializing.
deserialize_name(&self) -> String182 pub fn deserialize_name(&self) -> String {
183 self.deserialize.clone()
184 }
185
deserialize_aliases(&self) -> Vec<String>186 fn deserialize_aliases(&self) -> Vec<String> {
187 let mut aliases = self.deserialize_aliases.clone();
188 let main_name = self.deserialize_name();
189 if !aliases.contains(&main_name) {
190 aliases.push(main_name);
191 }
192 aliases
193 }
194 }
195
196 pub struct RenameAllRules {
197 serialize: RenameRule,
198 deserialize: RenameRule,
199 }
200
201 /// Represents struct or enum attribute information.
202 pub struct Container {
203 name: Name,
204 transparent: bool,
205 deny_unknown_fields: bool,
206 default: Default,
207 rename_all_rules: RenameAllRules,
208 ser_bound: Option<Vec<syn::WherePredicate>>,
209 de_bound: Option<Vec<syn::WherePredicate>>,
210 tag: TagType,
211 type_from: Option<syn::Type>,
212 type_try_from: Option<syn::Type>,
213 type_into: Option<syn::Type>,
214 remote: Option<syn::Path>,
215 identifier: Identifier,
216 has_flatten: bool,
217 serde_path: Option<syn::Path>,
218 is_packed: bool,
219 /// Error message generated when type can't be deserialized
220 expecting: Option<String>,
221 }
222
223 /// Styles of representing an enum.
224 pub enum TagType {
225 /// The default.
226 ///
227 /// ```json
228 /// {"variant1": {"key1": "value1", "key2": "value2"}}
229 /// ```
230 External,
231
232 /// `#[serde(tag = "type")]`
233 ///
234 /// ```json
235 /// {"type": "variant1", "key1": "value1", "key2": "value2"}
236 /// ```
237 Internal { tag: String },
238
239 /// `#[serde(tag = "t", content = "c")]`
240 ///
241 /// ```json
242 /// {"t": "variant1", "c": {"key1": "value1", "key2": "value2"}}
243 /// ```
244 Adjacent { tag: String, content: String },
245
246 /// `#[serde(untagged)]`
247 ///
248 /// ```json
249 /// {"key1": "value1", "key2": "value2"}
250 /// ```
251 None,
252 }
253
254 /// Whether this enum represents the fields of a struct or the variants of an
255 /// enum.
256 #[derive(Copy, Clone)]
257 pub enum Identifier {
258 /// It does not.
259 No,
260
261 /// This enum represents the fields of a struct. All of the variants must be
262 /// unit variants, except possibly one which is annotated with
263 /// `#[serde(other)]` and is a newtype variant.
264 Field,
265
266 /// This enum represents the variants of an enum. All of the variants must
267 /// be unit variants.
268 Variant,
269 }
270
271 impl Identifier {
272 #[cfg(feature = "deserialize_in_place")]
is_some(self) -> bool273 pub fn is_some(self) -> bool {
274 match self {
275 Identifier::No => false,
276 Identifier::Field | Identifier::Variant => true,
277 }
278 }
279 }
280
281 impl Container {
282 /// Extract out the `#[serde(...)]` attributes from an item.
from_ast(cx: &Ctxt, item: &syn::DeriveInput) -> Self283 pub fn from_ast(cx: &Ctxt, item: &syn::DeriveInput) -> Self {
284 let mut ser_name = Attr::none(cx, RENAME);
285 let mut de_name = Attr::none(cx, RENAME);
286 let mut transparent = BoolAttr::none(cx, TRANSPARENT);
287 let mut deny_unknown_fields = BoolAttr::none(cx, DENY_UNKNOWN_FIELDS);
288 let mut default = Attr::none(cx, DEFAULT);
289 let mut rename_all_ser_rule = Attr::none(cx, RENAME_ALL);
290 let mut rename_all_de_rule = Attr::none(cx, RENAME_ALL);
291 let mut ser_bound = Attr::none(cx, BOUND);
292 let mut de_bound = Attr::none(cx, BOUND);
293 let mut untagged = BoolAttr::none(cx, UNTAGGED);
294 let mut internal_tag = Attr::none(cx, TAG);
295 let mut content = Attr::none(cx, CONTENT);
296 let mut type_from = Attr::none(cx, FROM);
297 let mut type_try_from = Attr::none(cx, TRY_FROM);
298 let mut type_into = Attr::none(cx, INTO);
299 let mut remote = Attr::none(cx, REMOTE);
300 let mut field_identifier = BoolAttr::none(cx, FIELD_IDENTIFIER);
301 let mut variant_identifier = BoolAttr::none(cx, VARIANT_IDENTIFIER);
302 let mut serde_path = Attr::none(cx, CRATE);
303 let mut expecting = Attr::none(cx, EXPECTING);
304
305 for attr in &item.attrs {
306 if attr.path() != SERDE {
307 continue;
308 }
309
310 if let Err(err) = attr.parse_nested_meta(|meta| {
311 if meta.path == RENAME {
312 // #[serde(rename = "foo")]
313 // #[serde(rename(serialize = "foo", deserialize = "bar"))]
314 let (ser, de) = get_renames(cx, RENAME, &meta)?;
315 ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
316 de_name.set_opt(&meta.path, de.as_ref().map(syn::LitStr::value));
317 } else if meta.path == RENAME_ALL {
318 // #[serde(rename_all = "foo")]
319 // #[serde(rename_all(serialize = "foo", deserialize = "bar"))]
320 let one_name = meta.input.peek(Token![=]);
321 let (ser, de) = get_renames(cx, RENAME_ALL, &meta)?;
322 if let Some(ser) = ser {
323 match RenameRule::from_str(&ser.value()) {
324 Ok(rename_rule) => rename_all_ser_rule.set(&meta.path, rename_rule),
325 Err(err) => cx.error_spanned_by(ser, err),
326 }
327 }
328 if let Some(de) = de {
329 match RenameRule::from_str(&de.value()) {
330 Ok(rename_rule) => rename_all_de_rule.set(&meta.path, rename_rule),
331 Err(err) => {
332 if !one_name {
333 cx.error_spanned_by(de, err);
334 }
335 }
336 }
337 }
338 } else if meta.path == TRANSPARENT {
339 // #[serde(transparent)]
340 transparent.set_true(meta.path);
341 } else if meta.path == DENY_UNKNOWN_FIELDS {
342 // #[serde(deny_unknown_fields)]
343 deny_unknown_fields.set_true(meta.path);
344 } else if meta.path == DEFAULT {
345 if meta.input.peek(Token![=]) {
346 // #[serde(default = "...")]
347 if let Some(path) = parse_lit_into_expr_path(cx, DEFAULT, &meta)? {
348 match &item.data {
349 syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
350 syn::Fields::Named(_) => {
351 default.set(&meta.path, Default::Path(path));
352 }
353 syn::Fields::Unnamed(_) | syn::Fields::Unit => {
354 let msg = "#[serde(default = \"...\")] can only be used on structs with named fields";
355 cx.error_spanned_by(fields, msg);
356 }
357 },
358 syn::Data::Enum(syn::DataEnum { enum_token, .. }) => {
359 let msg = "#[serde(default = \"...\")] can only be used on structs with named fields";
360 cx.error_spanned_by(enum_token, msg);
361 }
362 syn::Data::Union(syn::DataUnion { union_token, .. }) => {
363 let msg = "#[serde(default = \"...\")] can only be used on structs with named fields";
364 cx.error_spanned_by(union_token, msg);
365 }
366 }
367 }
368 } else {
369 // #[serde(default)]
370 match &item.data {
371 syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
372 syn::Fields::Named(_) => {
373 default.set(meta.path, Default::Default);
374 }
375 syn::Fields::Unnamed(_) | syn::Fields::Unit => {
376 let msg = "#[serde(default)] can only be used on structs with named fields";
377 cx.error_spanned_by(fields, msg);
378 }
379 },
380 syn::Data::Enum(syn::DataEnum { enum_token, .. }) => {
381 let msg = "#[serde(default)] can only be used on structs with named fields";
382 cx.error_spanned_by(enum_token, msg);
383 }
384 syn::Data::Union(syn::DataUnion { union_token, .. }) => {
385 let msg = "#[serde(default)] can only be used on structs with named fields";
386 cx.error_spanned_by(union_token, msg);
387 }
388 }
389 }
390 } else if meta.path == BOUND {
391 // #[serde(bound = "T: SomeBound")]
392 // #[serde(bound(serialize = "...", deserialize = "..."))]
393 let (ser, de) = get_where_predicates(cx, &meta)?;
394 ser_bound.set_opt(&meta.path, ser);
395 de_bound.set_opt(&meta.path, de);
396 } else if meta.path == UNTAGGED {
397 // #[serde(untagged)]
398 match item.data {
399 syn::Data::Enum(_) => {
400 untagged.set_true(&meta.path);
401 }
402 syn::Data::Struct(syn::DataStruct { struct_token, .. }) => {
403 let msg = "#[serde(untagged)] can only be used on enums";
404 cx.error_spanned_by(struct_token, msg);
405 }
406 syn::Data::Union(syn::DataUnion { union_token, .. }) => {
407 let msg = "#[serde(untagged)] can only be used on enums";
408 cx.error_spanned_by(union_token, msg);
409 }
410 }
411 } else if meta.path == TAG {
412 // #[serde(tag = "type")]
413 if let Some(s) = get_lit_str(cx, TAG, &meta)? {
414 match &item.data {
415 syn::Data::Enum(_) => {
416 internal_tag.set(&meta.path, s.value());
417 }
418 syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
419 syn::Fields::Named(_) => {
420 internal_tag.set(&meta.path, s.value());
421 }
422 syn::Fields::Unnamed(_) | syn::Fields::Unit => {
423 let msg = "#[serde(tag = \"...\")] can only be used on enums and structs with named fields";
424 cx.error_spanned_by(fields, msg);
425 }
426 },
427 syn::Data::Union(syn::DataUnion { union_token, .. }) => {
428 let msg = "#[serde(tag = \"...\")] can only be used on enums and structs with named fields";
429 cx.error_spanned_by(union_token, msg);
430 }
431 }
432 }
433 } else if meta.path == CONTENT {
434 // #[serde(content = "c")]
435 if let Some(s) = get_lit_str(cx, CONTENT, &meta)? {
436 match &item.data {
437 syn::Data::Enum(_) => {
438 content.set(&meta.path, s.value());
439 }
440 syn::Data::Struct(syn::DataStruct { struct_token, .. }) => {
441 let msg = "#[serde(content = \"...\")] can only be used on enums";
442 cx.error_spanned_by(struct_token, msg);
443 }
444 syn::Data::Union(syn::DataUnion { union_token, .. }) => {
445 let msg = "#[serde(content = \"...\")] can only be used on enums";
446 cx.error_spanned_by(union_token, msg);
447 }
448 }
449 }
450 } else if meta.path == FROM {
451 // #[serde(from = "Type")]
452 if let Some(from_ty) = parse_lit_into_ty(cx, FROM, &meta)? {
453 type_from.set_opt(&meta.path, Some(from_ty));
454 }
455 } else if meta.path == TRY_FROM {
456 // #[serde(try_from = "Type")]
457 if let Some(try_from_ty) = parse_lit_into_ty(cx, TRY_FROM, &meta)? {
458 type_try_from.set_opt(&meta.path, Some(try_from_ty));
459 }
460 } else if meta.path == INTO {
461 // #[serde(into = "Type")]
462 if let Some(into_ty) = parse_lit_into_ty(cx, INTO, &meta)? {
463 type_into.set_opt(&meta.path, Some(into_ty));
464 }
465 } else if meta.path == REMOTE {
466 // #[serde(remote = "...")]
467 if let Some(path) = parse_lit_into_path(cx, REMOTE, &meta)? {
468 if is_primitive_path(&path, "Self") {
469 remote.set(&meta.path, item.ident.clone().into());
470 } else {
471 remote.set(&meta.path, path);
472 }
473 }
474 } else if meta.path == FIELD_IDENTIFIER {
475 // #[serde(field_identifier)]
476 field_identifier.set_true(&meta.path);
477 } else if meta.path == VARIANT_IDENTIFIER {
478 // #[serde(variant_identifier)]
479 variant_identifier.set_true(&meta.path);
480 } else if meta.path == CRATE {
481 // #[serde(crate = "foo")]
482 if let Some(path) = parse_lit_into_path(cx, CRATE, &meta)? {
483 serde_path.set(&meta.path, path);
484 }
485 } else if meta.path == EXPECTING {
486 // #[serde(expecting = "a message")]
487 if let Some(s) = get_lit_str(cx, EXPECTING, &meta)? {
488 expecting.set(&meta.path, s.value());
489 }
490 } else {
491 let path = meta.path.to_token_stream().to_string().replace(' ', "");
492 return Err(
493 meta.error(format_args!("unknown serde container attribute `{}`", path))
494 );
495 }
496 Ok(())
497 }) {
498 cx.syn_error(err);
499 }
500 }
501
502 let mut is_packed = false;
503 for attr in &item.attrs {
504 if attr.path() == REPR {
505 let _ = attr.parse_args_with(|input: ParseStream| {
506 while let Some(token) = input.parse()? {
507 if let TokenTree::Ident(ident) = token {
508 is_packed |= ident == "packed";
509 }
510 }
511 Ok(())
512 });
513 }
514 }
515
516 Container {
517 name: Name::from_attrs(unraw(&item.ident), ser_name, de_name, None),
518 transparent: transparent.get(),
519 deny_unknown_fields: deny_unknown_fields.get(),
520 default: default.get().unwrap_or(Default::None),
521 rename_all_rules: RenameAllRules {
522 serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
523 deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None),
524 },
525 ser_bound: ser_bound.get(),
526 de_bound: de_bound.get(),
527 tag: decide_tag(cx, item, untagged, internal_tag, content),
528 type_from: type_from.get(),
529 type_try_from: type_try_from.get(),
530 type_into: type_into.get(),
531 remote: remote.get(),
532 identifier: decide_identifier(cx, item, field_identifier, variant_identifier),
533 has_flatten: false,
534 serde_path: serde_path.get(),
535 is_packed,
536 expecting: expecting.get(),
537 }
538 }
539
name(&self) -> &Name540 pub fn name(&self) -> &Name {
541 &self.name
542 }
543
rename_all_rules(&self) -> &RenameAllRules544 pub fn rename_all_rules(&self) -> &RenameAllRules {
545 &self.rename_all_rules
546 }
547
transparent(&self) -> bool548 pub fn transparent(&self) -> bool {
549 self.transparent
550 }
551
deny_unknown_fields(&self) -> bool552 pub fn deny_unknown_fields(&self) -> bool {
553 self.deny_unknown_fields
554 }
555
default(&self) -> &Default556 pub fn default(&self) -> &Default {
557 &self.default
558 }
559
ser_bound(&self) -> Option<&[syn::WherePredicate]>560 pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
561 self.ser_bound.as_ref().map(|vec| &vec[..])
562 }
563
de_bound(&self) -> Option<&[syn::WherePredicate]>564 pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
565 self.de_bound.as_ref().map(|vec| &vec[..])
566 }
567
tag(&self) -> &TagType568 pub fn tag(&self) -> &TagType {
569 &self.tag
570 }
571
type_from(&self) -> Option<&syn::Type>572 pub fn type_from(&self) -> Option<&syn::Type> {
573 self.type_from.as_ref()
574 }
575
type_try_from(&self) -> Option<&syn::Type>576 pub fn type_try_from(&self) -> Option<&syn::Type> {
577 self.type_try_from.as_ref()
578 }
579
type_into(&self) -> Option<&syn::Type>580 pub fn type_into(&self) -> Option<&syn::Type> {
581 self.type_into.as_ref()
582 }
583
remote(&self) -> Option<&syn::Path>584 pub fn remote(&self) -> Option<&syn::Path> {
585 self.remote.as_ref()
586 }
587
is_packed(&self) -> bool588 pub fn is_packed(&self) -> bool {
589 self.is_packed
590 }
591
identifier(&self) -> Identifier592 pub fn identifier(&self) -> Identifier {
593 self.identifier
594 }
595
has_flatten(&self) -> bool596 pub fn has_flatten(&self) -> bool {
597 self.has_flatten
598 }
599
mark_has_flatten(&mut self)600 pub fn mark_has_flatten(&mut self) {
601 self.has_flatten = true;
602 }
603
custom_serde_path(&self) -> Option<&syn::Path>604 pub fn custom_serde_path(&self) -> Option<&syn::Path> {
605 self.serde_path.as_ref()
606 }
607
serde_path(&self) -> Cow<syn::Path>608 pub fn serde_path(&self) -> Cow<syn::Path> {
609 self.custom_serde_path()
610 .map_or_else(|| Cow::Owned(parse_quote!(_serde)), Cow::Borrowed)
611 }
612
613 /// Error message generated when type can't be deserialized.
614 /// If `None`, default message will be used
expecting(&self) -> Option<&str>615 pub fn expecting(&self) -> Option<&str> {
616 self.expecting.as_ref().map(String::as_ref)
617 }
618 }
619
decide_tag( cx: &Ctxt, item: &syn::DeriveInput, untagged: BoolAttr, internal_tag: Attr<String>, content: Attr<String>, ) -> TagType620 fn decide_tag(
621 cx: &Ctxt,
622 item: &syn::DeriveInput,
623 untagged: BoolAttr,
624 internal_tag: Attr<String>,
625 content: Attr<String>,
626 ) -> TagType {
627 match (
628 untagged.0.get_with_tokens(),
629 internal_tag.get_with_tokens(),
630 content.get_with_tokens(),
631 ) {
632 (None, None, None) => TagType::External,
633 (Some(_), None, None) => TagType::None,
634 (None, Some((_, tag)), None) => {
635 // Check that there are no tuple variants.
636 if let syn::Data::Enum(data) = &item.data {
637 for variant in &data.variants {
638 match &variant.fields {
639 syn::Fields::Named(_) | syn::Fields::Unit => {}
640 syn::Fields::Unnamed(fields) => {
641 if fields.unnamed.len() != 1 {
642 let msg =
643 "#[serde(tag = \"...\")] cannot be used with tuple variants";
644 cx.error_spanned_by(variant, msg);
645 break;
646 }
647 }
648 }
649 }
650 }
651 TagType::Internal { tag }
652 }
653 (Some((untagged_tokens, _)), Some((tag_tokens, _)), None) => {
654 let msg = "enum cannot be both untagged and internally tagged";
655 cx.error_spanned_by(untagged_tokens, msg);
656 cx.error_spanned_by(tag_tokens, msg);
657 TagType::External // doesn't matter, will error
658 }
659 (None, None, Some((content_tokens, _))) => {
660 let msg = "#[serde(tag = \"...\", content = \"...\")] must be used together";
661 cx.error_spanned_by(content_tokens, msg);
662 TagType::External
663 }
664 (Some((untagged_tokens, _)), None, Some((content_tokens, _))) => {
665 let msg = "untagged enum cannot have #[serde(content = \"...\")]";
666 cx.error_spanned_by(untagged_tokens, msg);
667 cx.error_spanned_by(content_tokens, msg);
668 TagType::External
669 }
670 (None, Some((_, tag)), Some((_, content))) => TagType::Adjacent { tag, content },
671 (Some((untagged_tokens, _)), Some((tag_tokens, _)), Some((content_tokens, _))) => {
672 let msg = "untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]";
673 cx.error_spanned_by(untagged_tokens, msg);
674 cx.error_spanned_by(tag_tokens, msg);
675 cx.error_spanned_by(content_tokens, msg);
676 TagType::External
677 }
678 }
679 }
680
decide_identifier( cx: &Ctxt, item: &syn::DeriveInput, field_identifier: BoolAttr, variant_identifier: BoolAttr, ) -> Identifier681 fn decide_identifier(
682 cx: &Ctxt,
683 item: &syn::DeriveInput,
684 field_identifier: BoolAttr,
685 variant_identifier: BoolAttr,
686 ) -> Identifier {
687 match (
688 &item.data,
689 field_identifier.0.get_with_tokens(),
690 variant_identifier.0.get_with_tokens(),
691 ) {
692 (_, None, None) => Identifier::No,
693 (_, Some((field_identifier_tokens, _)), Some((variant_identifier_tokens, _))) => {
694 let msg =
695 "#[serde(field_identifier)] and #[serde(variant_identifier)] cannot both be set";
696 cx.error_spanned_by(field_identifier_tokens, msg);
697 cx.error_spanned_by(variant_identifier_tokens, msg);
698 Identifier::No
699 }
700 (syn::Data::Enum(_), Some(_), None) => Identifier::Field,
701 (syn::Data::Enum(_), None, Some(_)) => Identifier::Variant,
702 (syn::Data::Struct(syn::DataStruct { struct_token, .. }), Some(_), None) => {
703 let msg = "#[serde(field_identifier)] can only be used on an enum";
704 cx.error_spanned_by(struct_token, msg);
705 Identifier::No
706 }
707 (syn::Data::Union(syn::DataUnion { union_token, .. }), Some(_), None) => {
708 let msg = "#[serde(field_identifier)] can only be used on an enum";
709 cx.error_spanned_by(union_token, msg);
710 Identifier::No
711 }
712 (syn::Data::Struct(syn::DataStruct { struct_token, .. }), None, Some(_)) => {
713 let msg = "#[serde(variant_identifier)] can only be used on an enum";
714 cx.error_spanned_by(struct_token, msg);
715 Identifier::No
716 }
717 (syn::Data::Union(syn::DataUnion { union_token, .. }), None, Some(_)) => {
718 let msg = "#[serde(variant_identifier)] can only be used on an enum";
719 cx.error_spanned_by(union_token, msg);
720 Identifier::No
721 }
722 }
723 }
724
725 /// Represents variant attribute information
726 pub struct Variant {
727 name: Name,
728 rename_all_rules: RenameAllRules,
729 ser_bound: Option<Vec<syn::WherePredicate>>,
730 de_bound: Option<Vec<syn::WherePredicate>>,
731 skip_deserializing: bool,
732 skip_serializing: bool,
733 other: bool,
734 serialize_with: Option<syn::ExprPath>,
735 deserialize_with: Option<syn::ExprPath>,
736 borrow: Option<BorrowAttribute>,
737 }
738
739 struct BorrowAttribute {
740 path: syn::Path,
741 lifetimes: Option<BTreeSet<syn::Lifetime>>,
742 }
743
744 impl Variant {
from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self745 pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self {
746 let mut ser_name = Attr::none(cx, RENAME);
747 let mut de_name = Attr::none(cx, RENAME);
748 let mut de_aliases = VecAttr::none(cx, RENAME);
749 let mut skip_deserializing = BoolAttr::none(cx, SKIP_DESERIALIZING);
750 let mut skip_serializing = BoolAttr::none(cx, SKIP_SERIALIZING);
751 let mut rename_all_ser_rule = Attr::none(cx, RENAME_ALL);
752 let mut rename_all_de_rule = Attr::none(cx, RENAME_ALL);
753 let mut ser_bound = Attr::none(cx, BOUND);
754 let mut de_bound = Attr::none(cx, BOUND);
755 let mut other = BoolAttr::none(cx, OTHER);
756 let mut serialize_with = Attr::none(cx, SERIALIZE_WITH);
757 let mut deserialize_with = Attr::none(cx, DESERIALIZE_WITH);
758 let mut borrow = Attr::none(cx, BORROW);
759
760 for attr in &variant.attrs {
761 if attr.path() != SERDE {
762 continue;
763 }
764
765 if let Err(err) = attr.parse_nested_meta(|meta| {
766 if meta.path == RENAME {
767 // #[serde(rename = "foo")]
768 // #[serde(rename(serialize = "foo", deserialize = "bar"))]
769 let (ser, de) = get_multiple_renames(cx, &meta)?;
770 ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
771 for de_value in de {
772 de_name.set_if_none(de_value.value());
773 de_aliases.insert(&meta.path, de_value.value());
774 }
775 } else if meta.path == ALIAS {
776 // #[serde(alias = "foo")]
777 if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
778 de_aliases.insert(&meta.path, s.value());
779 }
780 } else if meta.path == RENAME_ALL {
781 // #[serde(rename_all = "foo")]
782 // #[serde(rename_all(serialize = "foo", deserialize = "bar"))]
783 let one_name = meta.input.peek(Token![=]);
784 let (ser, de) = get_renames(cx, RENAME_ALL, &meta)?;
785 if let Some(ser) = ser {
786 match RenameRule::from_str(&ser.value()) {
787 Ok(rename_rule) => rename_all_ser_rule.set(&meta.path, rename_rule),
788 Err(err) => cx.error_spanned_by(ser, err),
789 }
790 }
791 if let Some(de) = de {
792 match RenameRule::from_str(&de.value()) {
793 Ok(rename_rule) => rename_all_de_rule.set(&meta.path, rename_rule),
794 Err(err) => {
795 if !one_name {
796 cx.error_spanned_by(de, err);
797 }
798 }
799 }
800 }
801 } else if meta.path == SKIP {
802 // #[serde(skip)]
803 skip_serializing.set_true(&meta.path);
804 skip_deserializing.set_true(&meta.path);
805 } else if meta.path == SKIP_DESERIALIZING {
806 // #[serde(skip_deserializing)]
807 skip_deserializing.set_true(&meta.path);
808 } else if meta.path == SKIP_SERIALIZING {
809 // #[serde(skip_serializing)]
810 skip_serializing.set_true(&meta.path);
811 } else if meta.path == OTHER {
812 // #[serde(other)]
813 other.set_true(&meta.path);
814 } else if meta.path == BOUND {
815 // #[serde(bound = "T: SomeBound")]
816 // #[serde(bound(serialize = "...", deserialize = "..."))]
817 let (ser, de) = get_where_predicates(cx, &meta)?;
818 ser_bound.set_opt(&meta.path, ser);
819 de_bound.set_opt(&meta.path, de);
820 } else if meta.path == WITH {
821 // #[serde(with = "...")]
822 if let Some(path) = parse_lit_into_expr_path(cx, WITH, &meta)? {
823 let mut ser_path = path.clone();
824 ser_path
825 .path
826 .segments
827 .push(Ident::new("serialize", Span::call_site()).into());
828 serialize_with.set(&meta.path, ser_path);
829 let mut de_path = path;
830 de_path
831 .path
832 .segments
833 .push(Ident::new("deserialize", Span::call_site()).into());
834 deserialize_with.set(&meta.path, de_path);
835 }
836 } else if meta.path == SERIALIZE_WITH {
837 // #[serde(serialize_with = "...")]
838 if let Some(path) = parse_lit_into_expr_path(cx, SERIALIZE_WITH, &meta)? {
839 serialize_with.set(&meta.path, path);
840 }
841 } else if meta.path == DESERIALIZE_WITH {
842 // #[serde(deserialize_with = "...")]
843 if let Some(path) = parse_lit_into_expr_path(cx, DESERIALIZE_WITH, &meta)? {
844 deserialize_with.set(&meta.path, path);
845 }
846 } else if meta.path == BORROW {
847 let borrow_attribute = if meta.input.peek(Token![=]) {
848 // #[serde(borrow = "'a + 'b")]
849 let lifetimes = parse_lit_into_lifetimes(cx, &meta)?;
850 BorrowAttribute {
851 path: meta.path.clone(),
852 lifetimes: Some(lifetimes),
853 }
854 } else {
855 // #[serde(borrow)]
856 BorrowAttribute {
857 path: meta.path.clone(),
858 lifetimes: None,
859 }
860 };
861 match &variant.fields {
862 syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => {
863 borrow.set(&meta.path, borrow_attribute);
864 }
865 _ => {
866 let msg = "#[serde(borrow)] may only be used on newtype variants";
867 cx.error_spanned_by(variant, msg);
868 }
869 }
870 } else {
871 let path = meta.path.to_token_stream().to_string().replace(' ', "");
872 return Err(
873 meta.error(format_args!("unknown serde variant attribute `{}`", path))
874 );
875 }
876 Ok(())
877 }) {
878 cx.syn_error(err);
879 }
880 }
881
882 Variant {
883 name: Name::from_attrs(unraw(&variant.ident), ser_name, de_name, Some(de_aliases)),
884 rename_all_rules: RenameAllRules {
885 serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
886 deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None),
887 },
888 ser_bound: ser_bound.get(),
889 de_bound: de_bound.get(),
890 skip_deserializing: skip_deserializing.get(),
891 skip_serializing: skip_serializing.get(),
892 other: other.get(),
893 serialize_with: serialize_with.get(),
894 deserialize_with: deserialize_with.get(),
895 borrow: borrow.get(),
896 }
897 }
898
name(&self) -> &Name899 pub fn name(&self) -> &Name {
900 &self.name
901 }
902
aliases(&self) -> Vec<String>903 pub fn aliases(&self) -> Vec<String> {
904 self.name.deserialize_aliases()
905 }
906
rename_by_rules(&mut self, rules: &RenameAllRules)907 pub fn rename_by_rules(&mut self, rules: &RenameAllRules) {
908 if !self.name.serialize_renamed {
909 self.name.serialize = rules.serialize.apply_to_variant(&self.name.serialize);
910 }
911 if !self.name.deserialize_renamed {
912 self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize);
913 }
914 }
915
rename_all_rules(&self) -> &RenameAllRules916 pub fn rename_all_rules(&self) -> &RenameAllRules {
917 &self.rename_all_rules
918 }
919
ser_bound(&self) -> Option<&[syn::WherePredicate]>920 pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
921 self.ser_bound.as_ref().map(|vec| &vec[..])
922 }
923
de_bound(&self) -> Option<&[syn::WherePredicate]>924 pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
925 self.de_bound.as_ref().map(|vec| &vec[..])
926 }
927
skip_deserializing(&self) -> bool928 pub fn skip_deserializing(&self) -> bool {
929 self.skip_deserializing
930 }
931
skip_serializing(&self) -> bool932 pub fn skip_serializing(&self) -> bool {
933 self.skip_serializing
934 }
935
other(&self) -> bool936 pub fn other(&self) -> bool {
937 self.other
938 }
939
serialize_with(&self) -> Option<&syn::ExprPath>940 pub fn serialize_with(&self) -> Option<&syn::ExprPath> {
941 self.serialize_with.as_ref()
942 }
943
deserialize_with(&self) -> Option<&syn::ExprPath>944 pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
945 self.deserialize_with.as_ref()
946 }
947 }
948
949 /// Represents field attribute information
950 pub struct Field {
951 name: Name,
952 skip_serializing: bool,
953 skip_deserializing: bool,
954 skip_serializing_if: Option<syn::ExprPath>,
955 default: Default,
956 serialize_with: Option<syn::ExprPath>,
957 deserialize_with: Option<syn::ExprPath>,
958 ser_bound: Option<Vec<syn::WherePredicate>>,
959 de_bound: Option<Vec<syn::WherePredicate>>,
960 borrowed_lifetimes: BTreeSet<syn::Lifetime>,
961 getter: Option<syn::ExprPath>,
962 flatten: bool,
963 transparent: bool,
964 }
965
966 /// Represents the default to use for a field when deserializing.
967 pub enum Default {
968 /// Field must always be specified because it does not have a default.
969 None,
970 /// The default is given by `std::default::Default::default()`.
971 Default,
972 /// The default is given by this function.
973 Path(syn::ExprPath),
974 }
975
976 impl Default {
is_none(&self) -> bool977 pub fn is_none(&self) -> bool {
978 match self {
979 Default::None => true,
980 Default::Default | Default::Path(_) => false,
981 }
982 }
983 }
984
985 impl Field {
986 /// Extract out the `#[serde(...)]` attributes from a struct field.
from_ast( cx: &Ctxt, index: usize, field: &syn::Field, attrs: Option<&Variant>, container_default: &Default, ) -> Self987 pub fn from_ast(
988 cx: &Ctxt,
989 index: usize,
990 field: &syn::Field,
991 attrs: Option<&Variant>,
992 container_default: &Default,
993 ) -> Self {
994 let mut ser_name = Attr::none(cx, RENAME);
995 let mut de_name = Attr::none(cx, RENAME);
996 let mut de_aliases = VecAttr::none(cx, RENAME);
997 let mut skip_serializing = BoolAttr::none(cx, SKIP_SERIALIZING);
998 let mut skip_deserializing = BoolAttr::none(cx, SKIP_DESERIALIZING);
999 let mut skip_serializing_if = Attr::none(cx, SKIP_SERIALIZING_IF);
1000 let mut default = Attr::none(cx, DEFAULT);
1001 let mut serialize_with = Attr::none(cx, SERIALIZE_WITH);
1002 let mut deserialize_with = Attr::none(cx, DESERIALIZE_WITH);
1003 let mut ser_bound = Attr::none(cx, BOUND);
1004 let mut de_bound = Attr::none(cx, BOUND);
1005 let mut borrowed_lifetimes = Attr::none(cx, BORROW);
1006 let mut getter = Attr::none(cx, GETTER);
1007 let mut flatten = BoolAttr::none(cx, FLATTEN);
1008
1009 let ident = match &field.ident {
1010 Some(ident) => unraw(ident),
1011 None => index.to_string(),
1012 };
1013
1014 if let Some(borrow_attribute) = attrs.and_then(|variant| variant.borrow.as_ref()) {
1015 if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) {
1016 if let Some(lifetimes) = &borrow_attribute.lifetimes {
1017 for lifetime in lifetimes {
1018 if !borrowable.contains(lifetime) {
1019 let msg =
1020 format!("field `{}` does not have lifetime {}", ident, lifetime);
1021 cx.error_spanned_by(field, msg);
1022 }
1023 }
1024 borrowed_lifetimes.set(&borrow_attribute.path, lifetimes.clone());
1025 } else {
1026 borrowed_lifetimes.set(&borrow_attribute.path, borrowable);
1027 }
1028 }
1029 }
1030
1031 for attr in &field.attrs {
1032 if attr.path() != SERDE {
1033 continue;
1034 }
1035
1036 if let Err(err) = attr.parse_nested_meta(|meta| {
1037 if meta.path == RENAME {
1038 // #[serde(rename = "foo")]
1039 // #[serde(rename(serialize = "foo", deserialize = "bar"))]
1040 let (ser, de) = get_multiple_renames(cx, &meta)?;
1041 ser_name.set_opt(&meta.path, ser.as_ref().map(syn::LitStr::value));
1042 for de_value in de {
1043 de_name.set_if_none(de_value.value());
1044 de_aliases.insert(&meta.path, de_value.value());
1045 }
1046 } else if meta.path == ALIAS {
1047 // #[serde(alias = "foo")]
1048 if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
1049 de_aliases.insert(&meta.path, s.value());
1050 }
1051 } else if meta.path == DEFAULT {
1052 if meta.input.peek(Token![=]) {
1053 // #[serde(default = "...")]
1054 if let Some(path) = parse_lit_into_expr_path(cx, DEFAULT, &meta)? {
1055 default.set(&meta.path, Default::Path(path));
1056 }
1057 } else {
1058 // #[serde(default)]
1059 default.set(&meta.path, Default::Default);
1060 }
1061 } else if meta.path == SKIP_SERIALIZING {
1062 // #[serde(skip_serializing)]
1063 skip_serializing.set_true(&meta.path);
1064 } else if meta.path == SKIP_DESERIALIZING {
1065 // #[serde(skip_deserializing)]
1066 skip_deserializing.set_true(&meta.path);
1067 } else if meta.path == SKIP {
1068 // #[serde(skip)]
1069 skip_serializing.set_true(&meta.path);
1070 skip_deserializing.set_true(&meta.path);
1071 } else if meta.path == SKIP_SERIALIZING_IF {
1072 // #[serde(skip_serializing_if = "...")]
1073 if let Some(path) = parse_lit_into_expr_path(cx, SKIP_SERIALIZING_IF, &meta)? {
1074 skip_serializing_if.set(&meta.path, path);
1075 }
1076 } else if meta.path == SERIALIZE_WITH {
1077 // #[serde(serialize_with = "...")]
1078 if let Some(path) = parse_lit_into_expr_path(cx, SERIALIZE_WITH, &meta)? {
1079 serialize_with.set(&meta.path, path);
1080 }
1081 } else if meta.path == DESERIALIZE_WITH {
1082 // #[serde(deserialize_with = "...")]
1083 if let Some(path) = parse_lit_into_expr_path(cx, DESERIALIZE_WITH, &meta)? {
1084 deserialize_with.set(&meta.path, path);
1085 }
1086 } else if meta.path == WITH {
1087 // #[serde(with = "...")]
1088 if let Some(path) = parse_lit_into_expr_path(cx, WITH, &meta)? {
1089 let mut ser_path = path.clone();
1090 ser_path
1091 .path
1092 .segments
1093 .push(Ident::new("serialize", Span::call_site()).into());
1094 serialize_with.set(&meta.path, ser_path);
1095 let mut de_path = path;
1096 de_path
1097 .path
1098 .segments
1099 .push(Ident::new("deserialize", Span::call_site()).into());
1100 deserialize_with.set(&meta.path, de_path);
1101 }
1102 } else if meta.path == BOUND {
1103 // #[serde(bound = "T: SomeBound")]
1104 // #[serde(bound(serialize = "...", deserialize = "..."))]
1105 let (ser, de) = get_where_predicates(cx, &meta)?;
1106 ser_bound.set_opt(&meta.path, ser);
1107 de_bound.set_opt(&meta.path, de);
1108 } else if meta.path == BORROW {
1109 if meta.input.peek(Token![=]) {
1110 // #[serde(borrow = "'a + 'b")]
1111 let lifetimes = parse_lit_into_lifetimes(cx, &meta)?;
1112 if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) {
1113 for lifetime in &lifetimes {
1114 if !borrowable.contains(lifetime) {
1115 let msg = format!(
1116 "field `{}` does not have lifetime {}",
1117 ident, lifetime,
1118 );
1119 cx.error_spanned_by(field, msg);
1120 }
1121 }
1122 borrowed_lifetimes.set(&meta.path, lifetimes);
1123 }
1124 } else {
1125 // #[serde(borrow)]
1126 if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) {
1127 borrowed_lifetimes.set(&meta.path, borrowable);
1128 }
1129 }
1130 } else if meta.path == GETTER {
1131 // #[serde(getter = "...")]
1132 if let Some(path) = parse_lit_into_expr_path(cx, GETTER, &meta)? {
1133 getter.set(&meta.path, path);
1134 }
1135 } else if meta.path == FLATTEN {
1136 // #[serde(flatten)]
1137 flatten.set_true(&meta.path);
1138 } else {
1139 let path = meta.path.to_token_stream().to_string().replace(' ', "");
1140 return Err(
1141 meta.error(format_args!("unknown serde field attribute `{}`", path))
1142 );
1143 }
1144 Ok(())
1145 }) {
1146 cx.syn_error(err);
1147 }
1148 }
1149
1150 // Is skip_deserializing, initialize the field to Default::default() unless a
1151 // different default is specified by `#[serde(default = "...")]` on
1152 // ourselves or our container (e.g. the struct we are in).
1153 if let Default::None = *container_default {
1154 if skip_deserializing.0.value.is_some() {
1155 default.set_if_none(Default::Default);
1156 }
1157 }
1158
1159 let mut borrowed_lifetimes = borrowed_lifetimes.get().unwrap_or_default();
1160 if !borrowed_lifetimes.is_empty() {
1161 // Cow<str> and Cow<[u8]> never borrow by default:
1162 //
1163 // impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
1164 //
1165 // A #[serde(borrow)] attribute enables borrowing that corresponds
1166 // roughly to these impls:
1167 //
1168 // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, str>
1169 // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]>
1170 if is_cow(&field.ty, is_str) {
1171 let mut path = syn::Path {
1172 leading_colon: None,
1173 segments: Punctuated::new(),
1174 };
1175 let span = Span::call_site();
1176 path.segments.push(Ident::new("_serde", span).into());
1177 path.segments.push(Ident::new("__private", span).into());
1178 path.segments.push(Ident::new("de", span).into());
1179 path.segments
1180 .push(Ident::new("borrow_cow_str", span).into());
1181 let expr = syn::ExprPath {
1182 attrs: Vec::new(),
1183 qself: None,
1184 path,
1185 };
1186 deserialize_with.set_if_none(expr);
1187 } else if is_cow(&field.ty, is_slice_u8) {
1188 let mut path = syn::Path {
1189 leading_colon: None,
1190 segments: Punctuated::new(),
1191 };
1192 let span = Span::call_site();
1193 path.segments.push(Ident::new("_serde", span).into());
1194 path.segments.push(Ident::new("__private", span).into());
1195 path.segments.push(Ident::new("de", span).into());
1196 path.segments
1197 .push(Ident::new("borrow_cow_bytes", span).into());
1198 let expr = syn::ExprPath {
1199 attrs: Vec::new(),
1200 qself: None,
1201 path,
1202 };
1203 deserialize_with.set_if_none(expr);
1204 }
1205 } else if is_implicitly_borrowed(&field.ty) {
1206 // Types &str and &[u8] are always implicitly borrowed. No need for
1207 // a #[serde(borrow)].
1208 collect_lifetimes(&field.ty, &mut borrowed_lifetimes);
1209 }
1210
1211 Field {
1212 name: Name::from_attrs(ident, ser_name, de_name, Some(de_aliases)),
1213 skip_serializing: skip_serializing.get(),
1214 skip_deserializing: skip_deserializing.get(),
1215 skip_serializing_if: skip_serializing_if.get(),
1216 default: default.get().unwrap_or(Default::None),
1217 serialize_with: serialize_with.get(),
1218 deserialize_with: deserialize_with.get(),
1219 ser_bound: ser_bound.get(),
1220 de_bound: de_bound.get(),
1221 borrowed_lifetimes,
1222 getter: getter.get(),
1223 flatten: flatten.get(),
1224 transparent: false,
1225 }
1226 }
1227
name(&self) -> &Name1228 pub fn name(&self) -> &Name {
1229 &self.name
1230 }
1231
aliases(&self) -> Vec<String>1232 pub fn aliases(&self) -> Vec<String> {
1233 self.name.deserialize_aliases()
1234 }
1235
rename_by_rules(&mut self, rules: &RenameAllRules)1236 pub fn rename_by_rules(&mut self, rules: &RenameAllRules) {
1237 if !self.name.serialize_renamed {
1238 self.name.serialize = rules.serialize.apply_to_field(&self.name.serialize);
1239 }
1240 if !self.name.deserialize_renamed {
1241 self.name.deserialize = rules.deserialize.apply_to_field(&self.name.deserialize);
1242 }
1243 }
1244
skip_serializing(&self) -> bool1245 pub fn skip_serializing(&self) -> bool {
1246 self.skip_serializing
1247 }
1248
skip_deserializing(&self) -> bool1249 pub fn skip_deserializing(&self) -> bool {
1250 self.skip_deserializing
1251 }
1252
skip_serializing_if(&self) -> Option<&syn::ExprPath>1253 pub fn skip_serializing_if(&self) -> Option<&syn::ExprPath> {
1254 self.skip_serializing_if.as_ref()
1255 }
1256
default(&self) -> &Default1257 pub fn default(&self) -> &Default {
1258 &self.default
1259 }
1260
serialize_with(&self) -> Option<&syn::ExprPath>1261 pub fn serialize_with(&self) -> Option<&syn::ExprPath> {
1262 self.serialize_with.as_ref()
1263 }
1264
deserialize_with(&self) -> Option<&syn::ExprPath>1265 pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
1266 self.deserialize_with.as_ref()
1267 }
1268
ser_bound(&self) -> Option<&[syn::WherePredicate]>1269 pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
1270 self.ser_bound.as_ref().map(|vec| &vec[..])
1271 }
1272
de_bound(&self) -> Option<&[syn::WherePredicate]>1273 pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
1274 self.de_bound.as_ref().map(|vec| &vec[..])
1275 }
1276
borrowed_lifetimes(&self) -> &BTreeSet<syn::Lifetime>1277 pub fn borrowed_lifetimes(&self) -> &BTreeSet<syn::Lifetime> {
1278 &self.borrowed_lifetimes
1279 }
1280
getter(&self) -> Option<&syn::ExprPath>1281 pub fn getter(&self) -> Option<&syn::ExprPath> {
1282 self.getter.as_ref()
1283 }
1284
flatten(&self) -> bool1285 pub fn flatten(&self) -> bool {
1286 self.flatten
1287 }
1288
transparent(&self) -> bool1289 pub fn transparent(&self) -> bool {
1290 self.transparent
1291 }
1292
mark_transparent(&mut self)1293 pub fn mark_transparent(&mut self) {
1294 self.transparent = true;
1295 }
1296 }
1297
1298 type SerAndDe<T> = (Option<T>, Option<T>);
1299
get_ser_and_de<'c, T, F, R>( cx: &'c Ctxt, attr_name: Symbol, meta: &ParseNestedMeta, f: F, ) -> syn::Result<(VecAttr<'c, T>, VecAttr<'c, T>)> where T: Clone, F: Fn(&Ctxt, Symbol, Symbol, &ParseNestedMeta) -> syn::Result<R>, R: Into<Option<T>>,1300 fn get_ser_and_de<'c, T, F, R>(
1301 cx: &'c Ctxt,
1302 attr_name: Symbol,
1303 meta: &ParseNestedMeta,
1304 f: F,
1305 ) -> syn::Result<(VecAttr<'c, T>, VecAttr<'c, T>)>
1306 where
1307 T: Clone,
1308 F: Fn(&Ctxt, Symbol, Symbol, &ParseNestedMeta) -> syn::Result<R>,
1309 R: Into<Option<T>>,
1310 {
1311 let mut ser_meta = VecAttr::none(cx, attr_name);
1312 let mut de_meta = VecAttr::none(cx, attr_name);
1313
1314 let lookahead = meta.input.lookahead1();
1315 if lookahead.peek(Token![=]) {
1316 if let Some(both) = f(cx, attr_name, attr_name, meta)?.into() {
1317 ser_meta.insert(&meta.path, both.clone());
1318 de_meta.insert(&meta.path, both);
1319 }
1320 } else if lookahead.peek(token::Paren) {
1321 meta.parse_nested_meta(|meta| {
1322 if meta.path == SERIALIZE {
1323 if let Some(v) = f(cx, attr_name, SERIALIZE, &meta)?.into() {
1324 ser_meta.insert(&meta.path, v);
1325 }
1326 } else if meta.path == DESERIALIZE {
1327 if let Some(v) = f(cx, attr_name, DESERIALIZE, &meta)?.into() {
1328 de_meta.insert(&meta.path, v);
1329 }
1330 } else {
1331 return Err(meta.error(format_args!(
1332 "malformed {0} attribute, expected `{0}(serialize = ..., deserialize = ...)`",
1333 attr_name,
1334 )));
1335 }
1336 Ok(())
1337 })?;
1338 } else {
1339 return Err(lookahead.error());
1340 }
1341
1342 Ok((ser_meta, de_meta))
1343 }
1344
get_renames( cx: &Ctxt, attr_name: Symbol, meta: &ParseNestedMeta, ) -> syn::Result<SerAndDe<syn::LitStr>>1345 fn get_renames(
1346 cx: &Ctxt,
1347 attr_name: Symbol,
1348 meta: &ParseNestedMeta,
1349 ) -> syn::Result<SerAndDe<syn::LitStr>> {
1350 let (ser, de) = get_ser_and_de(cx, attr_name, meta, get_lit_str2)?;
1351 Ok((ser.at_most_one(), de.at_most_one()))
1352 }
1353
get_multiple_renames( cx: &Ctxt, meta: &ParseNestedMeta, ) -> syn::Result<(Option<syn::LitStr>, Vec<syn::LitStr>)>1354 fn get_multiple_renames(
1355 cx: &Ctxt,
1356 meta: &ParseNestedMeta,
1357 ) -> syn::Result<(Option<syn::LitStr>, Vec<syn::LitStr>)> {
1358 let (ser, de) = get_ser_and_de(cx, RENAME, meta, get_lit_str2)?;
1359 Ok((ser.at_most_one(), de.get()))
1360 }
1361
get_where_predicates( cx: &Ctxt, meta: &ParseNestedMeta, ) -> syn::Result<SerAndDe<Vec<syn::WherePredicate>>>1362 fn get_where_predicates(
1363 cx: &Ctxt,
1364 meta: &ParseNestedMeta,
1365 ) -> syn::Result<SerAndDe<Vec<syn::WherePredicate>>> {
1366 let (ser, de) = get_ser_and_de(cx, BOUND, meta, parse_lit_into_where)?;
1367 Ok((ser.at_most_one(), de.at_most_one()))
1368 }
1369
get_lit_str( cx: &Ctxt, attr_name: Symbol, meta: &ParseNestedMeta, ) -> syn::Result<Option<syn::LitStr>>1370 fn get_lit_str(
1371 cx: &Ctxt,
1372 attr_name: Symbol,
1373 meta: &ParseNestedMeta,
1374 ) -> syn::Result<Option<syn::LitStr>> {
1375 get_lit_str2(cx, attr_name, attr_name, meta)
1376 }
1377
get_lit_str2( cx: &Ctxt, attr_name: Symbol, meta_item_name: Symbol, meta: &ParseNestedMeta, ) -> syn::Result<Option<syn::LitStr>>1378 fn get_lit_str2(
1379 cx: &Ctxt,
1380 attr_name: Symbol,
1381 meta_item_name: Symbol,
1382 meta: &ParseNestedMeta,
1383 ) -> syn::Result<Option<syn::LitStr>> {
1384 let expr: syn::Expr = meta.value()?.parse()?;
1385 let mut value = &expr;
1386 while let syn::Expr::Group(e) = value {
1387 value = &e.expr;
1388 }
1389 if let syn::Expr::Lit(syn::ExprLit {
1390 lit: syn::Lit::Str(lit),
1391 ..
1392 }) = value
1393 {
1394 Ok(Some(lit.clone()))
1395 } else {
1396 cx.error_spanned_by(
1397 expr,
1398 format!(
1399 "expected serde {} attribute to be a string: `{} = \"...\"`",
1400 attr_name, meta_item_name
1401 ),
1402 );
1403 Ok(None)
1404 }
1405 }
1406
parse_lit_into_path( cx: &Ctxt, attr_name: Symbol, meta: &ParseNestedMeta, ) -> syn::Result<Option<syn::Path>>1407 fn parse_lit_into_path(
1408 cx: &Ctxt,
1409 attr_name: Symbol,
1410 meta: &ParseNestedMeta,
1411 ) -> syn::Result<Option<syn::Path>> {
1412 let string = match get_lit_str(cx, attr_name, meta)? {
1413 Some(string) => string,
1414 None => return Ok(None),
1415 };
1416
1417 Ok(match string.parse() {
1418 Ok(path) => Some(path),
1419 Err(_) => {
1420 cx.error_spanned_by(
1421 &string,
1422 format!("failed to parse path: {:?}", string.value()),
1423 );
1424 None
1425 }
1426 })
1427 }
1428
parse_lit_into_expr_path( cx: &Ctxt, attr_name: Symbol, meta: &ParseNestedMeta, ) -> syn::Result<Option<syn::ExprPath>>1429 fn parse_lit_into_expr_path(
1430 cx: &Ctxt,
1431 attr_name: Symbol,
1432 meta: &ParseNestedMeta,
1433 ) -> syn::Result<Option<syn::ExprPath>> {
1434 let string = match get_lit_str(cx, attr_name, meta)? {
1435 Some(string) => string,
1436 None => return Ok(None),
1437 };
1438
1439 Ok(match string.parse() {
1440 Ok(expr) => Some(expr),
1441 Err(_) => {
1442 cx.error_spanned_by(
1443 &string,
1444 format!("failed to parse path: {:?}", string.value()),
1445 );
1446 None
1447 }
1448 })
1449 }
1450
parse_lit_into_where( cx: &Ctxt, attr_name: Symbol, meta_item_name: Symbol, meta: &ParseNestedMeta, ) -> syn::Result<Vec<syn::WherePredicate>>1451 fn parse_lit_into_where(
1452 cx: &Ctxt,
1453 attr_name: Symbol,
1454 meta_item_name: Symbol,
1455 meta: &ParseNestedMeta,
1456 ) -> syn::Result<Vec<syn::WherePredicate>> {
1457 let string = match get_lit_str2(cx, attr_name, meta_item_name, meta)? {
1458 Some(string) => string,
1459 None => return Ok(Vec::new()),
1460 };
1461
1462 Ok(
1463 match string.parse_with(Punctuated::<syn::WherePredicate, Token![,]>::parse_terminated) {
1464 Ok(predicates) => Vec::from_iter(predicates),
1465 Err(err) => {
1466 cx.error_spanned_by(string, err);
1467 Vec::new()
1468 }
1469 },
1470 )
1471 }
1472
parse_lit_into_ty( cx: &Ctxt, attr_name: Symbol, meta: &ParseNestedMeta, ) -> syn::Result<Option<syn::Type>>1473 fn parse_lit_into_ty(
1474 cx: &Ctxt,
1475 attr_name: Symbol,
1476 meta: &ParseNestedMeta,
1477 ) -> syn::Result<Option<syn::Type>> {
1478 let string = match get_lit_str(cx, attr_name, meta)? {
1479 Some(string) => string,
1480 None => return Ok(None),
1481 };
1482
1483 Ok(match string.parse() {
1484 Ok(ty) => Some(ty),
1485 Err(_) => {
1486 cx.error_spanned_by(
1487 &string,
1488 format!("failed to parse type: {} = {:?}", attr_name, string.value()),
1489 );
1490 None
1491 }
1492 })
1493 }
1494
1495 // Parses a string literal like "'a + 'b + 'c" containing a nonempty list of
1496 // lifetimes separated by `+`.
parse_lit_into_lifetimes( cx: &Ctxt, meta: &ParseNestedMeta, ) -> syn::Result<BTreeSet<syn::Lifetime>>1497 fn parse_lit_into_lifetimes(
1498 cx: &Ctxt,
1499 meta: &ParseNestedMeta,
1500 ) -> syn::Result<BTreeSet<syn::Lifetime>> {
1501 let string = match get_lit_str(cx, BORROW, meta)? {
1502 Some(string) => string,
1503 None => return Ok(BTreeSet::new()),
1504 };
1505
1506 if let Ok(lifetimes) = string.parse_with(|input: ParseStream| {
1507 let mut set = BTreeSet::new();
1508 while !input.is_empty() {
1509 let lifetime: Lifetime = input.parse()?;
1510 if !set.insert(lifetime.clone()) {
1511 cx.error_spanned_by(
1512 &string,
1513 format!("duplicate borrowed lifetime `{}`", lifetime),
1514 );
1515 }
1516 if input.is_empty() {
1517 break;
1518 }
1519 input.parse::<Token![+]>()?;
1520 }
1521 Ok(set)
1522 }) {
1523 if lifetimes.is_empty() {
1524 cx.error_spanned_by(string, "at least one lifetime must be borrowed");
1525 }
1526 return Ok(lifetimes);
1527 }
1528
1529 cx.error_spanned_by(
1530 &string,
1531 format!("failed to parse borrowed lifetimes: {:?}", string.value()),
1532 );
1533 Ok(BTreeSet::new())
1534 }
1535
is_implicitly_borrowed(ty: &syn::Type) -> bool1536 fn is_implicitly_borrowed(ty: &syn::Type) -> bool {
1537 is_implicitly_borrowed_reference(ty) || is_option(ty, is_implicitly_borrowed_reference)
1538 }
1539
is_implicitly_borrowed_reference(ty: &syn::Type) -> bool1540 fn is_implicitly_borrowed_reference(ty: &syn::Type) -> bool {
1541 is_reference(ty, is_str) || is_reference(ty, is_slice_u8)
1542 }
1543
1544 // Whether the type looks like it might be `std::borrow::Cow<T>` where elem="T".
1545 // This can have false negatives and false positives.
1546 //
1547 // False negative:
1548 //
1549 // use std::borrow::Cow as Pig;
1550 //
1551 // #[derive(Deserialize)]
1552 // struct S<'a> {
1553 // #[serde(borrow)]
1554 // pig: Pig<'a, str>,
1555 // }
1556 //
1557 // False positive:
1558 //
1559 // type str = [i16];
1560 //
1561 // #[derive(Deserialize)]
1562 // struct S<'a> {
1563 // #[serde(borrow)]
1564 // cow: Cow<'a, str>,
1565 // }
is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool1566 fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
1567 let path = match ungroup(ty) {
1568 syn::Type::Path(ty) => &ty.path,
1569 _ => {
1570 return false;
1571 }
1572 };
1573 let seg = match path.segments.last() {
1574 Some(seg) => seg,
1575 None => {
1576 return false;
1577 }
1578 };
1579 let args = match &seg.arguments {
1580 syn::PathArguments::AngleBracketed(bracketed) => &bracketed.args,
1581 _ => {
1582 return false;
1583 }
1584 };
1585 seg.ident == "Cow"
1586 && args.len() == 2
1587 && match (&args[0], &args[1]) {
1588 (syn::GenericArgument::Lifetime(_), syn::GenericArgument::Type(arg)) => elem(arg),
1589 _ => false,
1590 }
1591 }
1592
is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool1593 fn is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
1594 let path = match ungroup(ty) {
1595 syn::Type::Path(ty) => &ty.path,
1596 _ => {
1597 return false;
1598 }
1599 };
1600 let seg = match path.segments.last() {
1601 Some(seg) => seg,
1602 None => {
1603 return false;
1604 }
1605 };
1606 let args = match &seg.arguments {
1607 syn::PathArguments::AngleBracketed(bracketed) => &bracketed.args,
1608 _ => {
1609 return false;
1610 }
1611 };
1612 seg.ident == "Option"
1613 && args.len() == 1
1614 && match &args[0] {
1615 syn::GenericArgument::Type(arg) => elem(arg),
1616 _ => false,
1617 }
1618 }
1619
1620 // Whether the type looks like it might be `&T` where elem="T". This can have
1621 // false negatives and false positives.
1622 //
1623 // False negative:
1624 //
1625 // type Yarn = str;
1626 //
1627 // #[derive(Deserialize)]
1628 // struct S<'a> {
1629 // r: &'a Yarn,
1630 // }
1631 //
1632 // False positive:
1633 //
1634 // type str = [i16];
1635 //
1636 // #[derive(Deserialize)]
1637 // struct S<'a> {
1638 // r: &'a str,
1639 // }
is_reference(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool1640 fn is_reference(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
1641 match ungroup(ty) {
1642 syn::Type::Reference(ty) => ty.mutability.is_none() && elem(&ty.elem),
1643 _ => false,
1644 }
1645 }
1646
is_str(ty: &syn::Type) -> bool1647 fn is_str(ty: &syn::Type) -> bool {
1648 is_primitive_type(ty, "str")
1649 }
1650
is_slice_u8(ty: &syn::Type) -> bool1651 fn is_slice_u8(ty: &syn::Type) -> bool {
1652 match ungroup(ty) {
1653 syn::Type::Slice(ty) => is_primitive_type(&ty.elem, "u8"),
1654 _ => false,
1655 }
1656 }
1657
is_primitive_type(ty: &syn::Type, primitive: &str) -> bool1658 fn is_primitive_type(ty: &syn::Type, primitive: &str) -> bool {
1659 match ungroup(ty) {
1660 syn::Type::Path(ty) => ty.qself.is_none() && is_primitive_path(&ty.path, primitive),
1661 _ => false,
1662 }
1663 }
1664
is_primitive_path(path: &syn::Path, primitive: &str) -> bool1665 fn is_primitive_path(path: &syn::Path, primitive: &str) -> bool {
1666 path.leading_colon.is_none()
1667 && path.segments.len() == 1
1668 && path.segments[0].ident == primitive
1669 && path.segments[0].arguments.is_empty()
1670 }
1671
1672 // All lifetimes that this type could borrow from a Deserializer.
1673 //
1674 // For example a type `S<'a, 'b>` could borrow `'a` and `'b`. On the other hand
1675 // a type `for<'a> fn(&'a str)` could not borrow `'a` from the Deserializer.
1676 //
1677 // This is used when there is an explicit or implicit `#[serde(borrow)]`
1678 // attribute on the field so there must be at least one borrowable lifetime.
borrowable_lifetimes( cx: &Ctxt, name: &str, field: &syn::Field, ) -> Result<BTreeSet<syn::Lifetime>, ()>1679 fn borrowable_lifetimes(
1680 cx: &Ctxt,
1681 name: &str,
1682 field: &syn::Field,
1683 ) -> Result<BTreeSet<syn::Lifetime>, ()> {
1684 let mut lifetimes = BTreeSet::new();
1685 collect_lifetimes(&field.ty, &mut lifetimes);
1686 if lifetimes.is_empty() {
1687 let msg = format!("field `{}` has no lifetimes to borrow", name);
1688 cx.error_spanned_by(field, msg);
1689 Err(())
1690 } else {
1691 Ok(lifetimes)
1692 }
1693 }
1694
collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet<syn::Lifetime>)1695 fn collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet<syn::Lifetime>) {
1696 match ty {
1697 syn::Type::Slice(ty) => {
1698 collect_lifetimes(&ty.elem, out);
1699 }
1700 syn::Type::Array(ty) => {
1701 collect_lifetimes(&ty.elem, out);
1702 }
1703 syn::Type::Ptr(ty) => {
1704 collect_lifetimes(&ty.elem, out);
1705 }
1706 syn::Type::Reference(ty) => {
1707 out.extend(ty.lifetime.iter().cloned());
1708 collect_lifetimes(&ty.elem, out);
1709 }
1710 syn::Type::Tuple(ty) => {
1711 for elem in &ty.elems {
1712 collect_lifetimes(elem, out);
1713 }
1714 }
1715 syn::Type::Path(ty) => {
1716 if let Some(qself) = &ty.qself {
1717 collect_lifetimes(&qself.ty, out);
1718 }
1719 for seg in &ty.path.segments {
1720 if let syn::PathArguments::AngleBracketed(bracketed) = &seg.arguments {
1721 for arg in &bracketed.args {
1722 match arg {
1723 syn::GenericArgument::Lifetime(lifetime) => {
1724 out.insert(lifetime.clone());
1725 }
1726 syn::GenericArgument::Type(ty) => {
1727 collect_lifetimes(ty, out);
1728 }
1729 syn::GenericArgument::AssocType(binding) => {
1730 collect_lifetimes(&binding.ty, out);
1731 }
1732 _ => {}
1733 }
1734 }
1735 }
1736 }
1737 }
1738 syn::Type::Paren(ty) => {
1739 collect_lifetimes(&ty.elem, out);
1740 }
1741 syn::Type::Group(ty) => {
1742 collect_lifetimes(&ty.elem, out);
1743 }
1744 syn::Type::Macro(ty) => {
1745 collect_lifetimes_from_tokens(ty.mac.tokens.clone(), out);
1746 }
1747 syn::Type::BareFn(_)
1748 | syn::Type::Never(_)
1749 | syn::Type::TraitObject(_)
1750 | syn::Type::ImplTrait(_)
1751 | syn::Type::Infer(_)
1752 | syn::Type::Verbatim(_) => {}
1753
1754 #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1755 _ => {}
1756 }
1757 }
1758
collect_lifetimes_from_tokens(tokens: TokenStream, out: &mut BTreeSet<syn::Lifetime>)1759 fn collect_lifetimes_from_tokens(tokens: TokenStream, out: &mut BTreeSet<syn::Lifetime>) {
1760 let mut iter = tokens.into_iter();
1761 while let Some(tt) = iter.next() {
1762 match &tt {
1763 TokenTree::Punct(op) if op.as_char() == '\'' && op.spacing() == Spacing::Joint => {
1764 if let Some(TokenTree::Ident(ident)) = iter.next() {
1765 out.insert(syn::Lifetime {
1766 apostrophe: op.span(),
1767 ident,
1768 });
1769 }
1770 }
1771 TokenTree::Group(group) => {
1772 let tokens = group.stream();
1773 collect_lifetimes_from_tokens(tokens, out);
1774 }
1775 _ => {}
1776 }
1777 }
1778 }
1779