serde_derive/internals/
attr.rs

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