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