serde_derive_internals/src/
attr.rs

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