Skip to main content

serde_derive/internals/
attr.rs

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