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
14pub use crate::internals::case::RenameRule;
23
24pub(crate) struct Attr<'c, T> {
25 cx: &'c Ctxt,
26 name: Symbol,
27 tokens: TokenStream,
28 value: Option<T>,
29}
30
31impl<'c, T> Attr<'c, T> {
32 fn none(cx: &'c Ctxt, name: Symbol) -> Self {
33 Attr {
34 cx,
35 name,
36 tokens: TokenStream::new(),
37 value: None,
38 }
39 }
40
41 fn set<A: ToTokens>(&mut self, obj: A, value: T) {
42 let tokens = obj.into_token_stream();
43
44 if self.value.is_some() {
45 let msg = format!("duplicate serde attribute `{}`", self.name);
46 self.cx.error_spanned_by(tokens, msg);
47 } else {
48 self.tokens = tokens;
49 self.value = Some(value);
50 }
51 }
52
53 fn set_opt<A: ToTokens>(&mut self, obj: A, value: Option<T>) {
54 if let Some(value) = value {
55 self.set(obj, value);
56 }
57 }
58
59 fn set_if_none(&mut self, value: T) {
60 if self.value.is_none() {
61 self.value = Some(value);
62 }
63 }
64
65 pub(crate) fn get(self) -> Option<T> {
66 self.value
67 }
68
69 fn get_with_tokens(self) -> Option<(TokenStream, T)> {
70 match self.value {
71 Some(v) => Some((self.tokens, v)),
72 None => None,
73 }
74 }
75}
76
77struct BoolAttr<'c>(Attr<'c, ()>);
78
79impl<'c> BoolAttr<'c> {
80 fn none(cx: &'c Ctxt, name: Symbol) -> Self {
81 BoolAttr(Attr::none(cx, name))
82 }
83
84 fn set_true<A: ToTokens>(&mut self, obj: A) {
85 self.0.set(obj, ());
86 }
87
88 fn get(&self) -> bool {
89 self.0.value.is_some()
90 }
91}
92
93pub(crate) struct VecAttr<'c, T> {
94 cx: &'c Ctxt,
95 name: Symbol,
96 first_dup_tokens: TokenStream,
97 values: Vec<T>,
98}
99
100impl<'c, T> VecAttr<'c, T> {
101 fn none(cx: &'c Ctxt, name: Symbol) -> Self {
102 VecAttr {
103 cx,
104 name,
105 first_dup_tokens: TokenStream::new(),
106 values: Vec::new(),
107 }
108 }
109
110 fn insert<A: ToTokens>(&mut self, obj: A, value: T) {
111 if self.values.len() == 1 {
112 self.first_dup_tokens = obj.into_token_stream();
113 }
114 self.values.push(value);
115 }
116
117 fn at_most_one(mut self) -> Option<T> {
118 if self.values.len() > 1 {
119 let dup_token = self.first_dup_tokens;
120 let msg = format!("duplicate serde attribute `{}`", self.name);
121 self.cx.error_spanned_by(dup_token, msg);
122 None
123 } else {
124 self.values.pop()
125 }
126 }
127
128 pub(crate) fn get(self) -> Vec<T> {
129 self.values
130 }
131}
132
133fn unraw(ident: &Ident) -> Ident {
134 Ident::new(ident.to_string().trim_start_matches("r#"), ident.span())
135}
136
137#[derive(Copy, Clone)]
138pub struct RenameAllRules {
139 pub serialize: RenameRule,
140 pub deserialize: RenameRule,
141}
142
143impl RenameAllRules {
144 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
154pub 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 expecting: Option<String>,
174 non_exhaustive: bool,
175}
176
177pub enum TagType {
179 External,
185
186 Internal { tag: String },
192
193 Adjacent { tag: String, content: String },
199
200 None,
206}
207
208#[derive(Copy, Clone)]
211pub enum Identifier {
212 No,
214
215 Field,
219
220 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 pub fn from_ast(cx: &Ctxt, item: &syn::DeriveInput) -> Self {
238 let mut ser_name = Attr::none(cx, RENAME);
239 let mut de_name = Attr::none(cx, RENAME);
240 let mut transparent = BoolAttr::none(cx, TRANSPARENT);
241 let mut deny_unknown_fields = BoolAttr::none(cx, DENY_UNKNOWN_FIELDS);
242 let mut default = Attr::none(cx, DEFAULT);
243 let mut rename_all_ser_rule = Attr::none(cx, RENAME_ALL);
244 let mut rename_all_de_rule = Attr::none(cx, RENAME_ALL);
245 let mut rename_all_fields_ser_rule = Attr::none(cx, RENAME_ALL_FIELDS);
246 let mut rename_all_fields_de_rule = Attr::none(cx, RENAME_ALL_FIELDS);
247 let mut ser_bound = Attr::none(cx, BOUND);
248 let mut de_bound = Attr::none(cx, BOUND);
249 let mut untagged = BoolAttr::none(cx, UNTAGGED);
250 let mut internal_tag = Attr::none(cx, TAG);
251 let mut content = Attr::none(cx, CONTENT);
252 let mut type_from = Attr::none(cx, FROM);
253 let mut type_try_from = Attr::none(cx, TRY_FROM);
254 let mut type_into = Attr::none(cx, INTO);
255 let mut remote = Attr::none(cx, REMOTE);
256 let mut field_identifier = BoolAttr::none(cx, FIELD_IDENTIFIER);
257 let mut variant_identifier = BoolAttr::none(cx, VARIANT_IDENTIFIER);
258 let mut serde_path = Attr::none(cx, CRATE);
259 let mut expecting = Attr::none(cx, EXPECTING);
260 let mut non_exhaustive = false;
261
262 for attr in &item.attrs {
263 if attr.path() != SERDE {
264 non_exhaustive |=
265 matches!(&attr.meta, syn::Meta::Path(path) if path == NON_EXHAUSTIVE);
266 continue;
267 }
268
269 if let syn::Meta::List(meta) = &attr.meta {
270 if meta.tokens.is_empty() {
271 continue;
272 }
273 }
274
275 if let Err(err) = attr.parse_nested_meta(|meta| {
276 if meta.path == RENAME {
277 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 let one_name = meta.input.peek(Token![=]);
286 let (ser, de) = get_renames(cx, RENAME_ALL, &meta)?;
287 if let Some(ser) = ser {
288 match RenameRule::from_str(&ser.value()) {
289 Ok(rename_rule) => rename_all_ser_rule.set(&meta.path, rename_rule),
290 Err(err) => cx.error_spanned_by(ser, err),
291 }
292 }
293 if let Some(de) = de {
294 match RenameRule::from_str(&de.value()) {
295 Ok(rename_rule) => rename_all_de_rule.set(&meta.path, rename_rule),
296 Err(err) => {
297 if !one_name {
298 cx.error_spanned_by(de, err);
299 }
300 }
301 }
302 }
303 } else if meta.path == RENAME_ALL_FIELDS {
304 let one_name = meta.input.peek(Token![=]);
307 let (ser, de) = get_renames(cx, RENAME_ALL_FIELDS, &meta)?;
308
309 match item.data {
310 syn::Data::Enum(_) => {
311 if let Some(ser) = ser {
312 match RenameRule::from_str(&ser.value()) {
313 Ok(rename_rule) => {
314 rename_all_fields_ser_rule.set(&meta.path, rename_rule);
315 }
316 Err(err) => cx.error_spanned_by(ser, err),
317 }
318 }
319 if let Some(de) = de {
320 match RenameRule::from_str(&de.value()) {
321 Ok(rename_rule) => {
322 rename_all_fields_de_rule.set(&meta.path, rename_rule);
323 }
324 Err(err) => {
325 if !one_name {
326 cx.error_spanned_by(de, err);
327 }
328 }
329 }
330 }
331 }
332 syn::Data::Struct(_) => {
333 let msg = "#[serde(rename_all_fields)] can only be used on enums";
334 cx.syn_error(meta.error(msg));
335 }
336 syn::Data::Union(_) => {
337 let msg = "#[serde(rename_all_fields)] can only be used on enums";
338 cx.syn_error(meta.error(msg));
339 }
340 }
341 } else if meta.path == TRANSPARENT {
342 transparent.set_true(meta.path);
344 } else if meta.path == DENY_UNKNOWN_FIELDS {
345 deny_unknown_fields.set_true(meta.path);
347 } else if meta.path == DEFAULT {
348 if meta.input.peek(Token![=]) {
349 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 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 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 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 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 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 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 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 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 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 field_identifier.set_true(&meta.path);
480 } else if meta.path == VARIANT_IDENTIFIER {
481 variant_identifier.set_true(&meta.path);
483 } else if meta.path == CRATE {
484 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 if let Some(s) = get_lit_str(cx, EXPECTING, &meta)? {
491 expecting.set(&meta.path, s.value());
492 }
493 } else {
494 let path = meta.path.to_token_stream().to_string().replace(' ', "");
495 return Err(
496 meta.error(format_args!("unknown serde container attribute `{}`", path))
497 );
498 }
499 Ok(())
500 }) {
501 cx.syn_error(err);
502 }
503 }
504
505 let mut is_packed = false;
506 for attr in &item.attrs {
507 if attr.path() == REPR {
508 let _ = attr.parse_args_with(|input: ParseStream| {
509 while let Some(token) = input.parse()? {
510 if let TokenTree::Ident(ident) = token {
511 is_packed |= ident == "packed";
512 }
513 }
514 Ok(())
515 });
516 }
517 }
518
519 Container {
520 name: MultiName::from_attrs(Name::from(&unraw(&item.ident)), ser_name, de_name, None),
521 transparent: transparent.get(),
522 deny_unknown_fields: deny_unknown_fields.get(),
523 default: default.get().unwrap_or(Default::None),
524 rename_all_rules: RenameAllRules {
525 serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
526 deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None),
527 },
528 rename_all_fields_rules: RenameAllRules {
529 serialize: rename_all_fields_ser_rule.get().unwrap_or(RenameRule::None),
530 deserialize: rename_all_fields_de_rule.get().unwrap_or(RenameRule::None),
531 },
532 ser_bound: ser_bound.get(),
533 de_bound: de_bound.get(),
534 tag: decide_tag(cx, item, untagged, internal_tag, content),
535 type_from: type_from.get(),
536 type_try_from: type_try_from.get(),
537 type_into: type_into.get(),
538 remote: remote.get(),
539 identifier: decide_identifier(cx, item, field_identifier, variant_identifier),
540 serde_path: serde_path.get(),
541 is_packed,
542 expecting: expecting.get(),
543 non_exhaustive,
544 }
545 }
546
547 pub fn name(&self) -> &MultiName {
548 &self.name
549 }
550
551 pub fn rename_all_rules(&self) -> RenameAllRules {
552 self.rename_all_rules
553 }
554
555 pub fn rename_all_fields_rules(&self) -> RenameAllRules {
556 self.rename_all_fields_rules
557 }
558
559 pub fn transparent(&self) -> bool {
560 self.transparent
561 }
562
563 pub fn deny_unknown_fields(&self) -> bool {
564 self.deny_unknown_fields
565 }
566
567 pub fn default(&self) -> &Default {
568 &self.default
569 }
570
571 pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
572 self.ser_bound.as_ref().map(|vec| &vec[..])
573 }
574
575 pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
576 self.de_bound.as_ref().map(|vec| &vec[..])
577 }
578
579 pub fn tag(&self) -> &TagType {
580 &self.tag
581 }
582
583 pub fn type_from(&self) -> Option<&syn::Type> {
584 self.type_from.as_ref()
585 }
586
587 pub fn type_try_from(&self) -> Option<&syn::Type> {
588 self.type_try_from.as_ref()
589 }
590
591 pub fn type_into(&self) -> Option<&syn::Type> {
592 self.type_into.as_ref()
593 }
594
595 pub fn remote(&self) -> Option<&syn::Path> {
596 self.remote.as_ref()
597 }
598
599 pub fn is_packed(&self) -> bool {
600 self.is_packed
601 }
602
603 pub fn identifier(&self) -> Identifier {
604 self.identifier
605 }
606
607 pub fn custom_serde_path(&self) -> Option<&syn::Path> {
608 self.serde_path.as_ref()
609 }
610
611 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 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 }
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
727pub 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 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 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 let one_name = meta.input.peek(Token![=]);
794 let (ser, de) = get_renames(cx, RENAME_ALL, &meta)?;
795 if let Some(ser) = ser {
796 match RenameRule::from_str(&ser.value()) {
797 Ok(rename_rule) => rename_all_ser_rule.set(&meta.path, rename_rule),
798 Err(err) => cx.error_spanned_by(ser, err),
799 }
800 }
801 if let Some(de) = de {
802 match RenameRule::from_str(&de.value()) {
803 Ok(rename_rule) => rename_all_de_rule.set(&meta.path, rename_rule),
804 Err(err) => {
805 if !one_name {
806 cx.error_spanned_by(de, err);
807 }
808 }
809 }
810 }
811 } else if meta.path == SKIP {
812 skip_serializing.set_true(&meta.path);
814 skip_deserializing.set_true(&meta.path);
815 } else if meta.path == SKIP_DESERIALIZING {
816 skip_deserializing.set_true(&meta.path);
818 } else if meta.path == SKIP_SERIALIZING {
819 skip_serializing.set_true(&meta.path);
821 } else if meta.path == OTHER {
822 other.set_true(&meta.path);
824 } else if meta.path == BOUND {
825 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 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 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 if let Some(path) = parse_lit_into_expr_path(cx, DESERIALIZE_WITH, &meta)? {
854 deserialize_with.set(&meta.path, path);
855 }
856 } else if meta.path == BORROW {
857 let borrow_attribute = if meta.input.peek(Token![=]) {
858 let lifetimes = parse_lit_into_lifetimes(cx, &meta)?;
860 BorrowAttribute {
861 path: meta.path.clone(),
862 lifetimes: Some(lifetimes),
863 }
864 } else {
865 BorrowAttribute {
867 path: meta.path.clone(),
868 lifetimes: None,
869 }
870 };
871 match &variant.fields {
872 syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => {
873 borrow.set(&meta.path, borrow_attribute);
874 }
875 _ => {
876 let msg = "#[serde(borrow)] may only be used on newtype variants";
877 cx.error_spanned_by(variant, msg);
878 }
879 }
880 } else if meta.path == UNTAGGED {
881 untagged.set_true(&meta.path);
882 } else {
883 let path = meta.path.to_token_stream().to_string().replace(' ', "");
884 return Err(
885 meta.error(format_args!("unknown serde variant attribute `{}`", path))
886 );
887 }
888 Ok(())
889 }) {
890 cx.syn_error(err);
891 }
892 }
893
894 Variant {
895 name: MultiName::from_attrs(
896 Name::from(&unraw(&variant.ident)),
897 ser_name,
898 de_name,
899 Some(de_aliases),
900 ),
901 rename_all_rules: RenameAllRules {
902 serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
903 deserialize: rename_all_de_rule.get().unwrap_or(RenameRule::None),
904 },
905 ser_bound: ser_bound.get(),
906 de_bound: de_bound.get(),
907 skip_deserializing: skip_deserializing.get(),
908 skip_serializing: skip_serializing.get(),
909 other: other.get(),
910 serialize_with: serialize_with.get(),
911 deserialize_with: deserialize_with.get(),
912 borrow: borrow.get(),
913 untagged: untagged.get(),
914 }
915 }
916
917 pub fn name(&self) -> &MultiName {
918 &self.name
919 }
920
921 pub fn aliases(&self) -> &BTreeSet<Name> {
922 self.name.deserialize_aliases()
923 }
924
925 pub fn rename_by_rules(&mut self, rules: RenameAllRules) {
926 if !self.name.serialize_renamed {
927 self.name.serialize.value =
928 rules.serialize.apply_to_variant(&self.name.serialize.value);
929 }
930 if !self.name.deserialize_renamed {
931 self.name.deserialize.value = rules
932 .deserialize
933 .apply_to_variant(&self.name.deserialize.value);
934 }
935 self.name
936 .deserialize_aliases
937 .insert(self.name.deserialize.clone());
938 }
939
940 pub fn rename_all_rules(&self) -> RenameAllRules {
941 self.rename_all_rules
942 }
943
944 pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
945 self.ser_bound.as_ref().map(|vec| &vec[..])
946 }
947
948 pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
949 self.de_bound.as_ref().map(|vec| &vec[..])
950 }
951
952 pub fn skip_deserializing(&self) -> bool {
953 self.skip_deserializing
954 }
955
956 pub fn skip_serializing(&self) -> bool {
957 self.skip_serializing
958 }
959
960 pub fn other(&self) -> bool {
961 self.other
962 }
963
964 pub fn serialize_with(&self) -> Option<&syn::ExprPath> {
965 self.serialize_with.as_ref()
966 }
967
968 pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
969 self.deserialize_with.as_ref()
970 }
971
972 pub fn untagged(&self) -> bool {
973 self.untagged
974 }
975}
976
977pub 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
994pub enum Default {
996 None,
998 Default,
1000 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 pub fn from_ast(
1016 cx: &Ctxt,
1017 index: usize,
1018 field: &syn::Field,
1019 attrs: Option<&Variant>,
1020 container_default: &Default,
1021 private: &Ident,
1022 ) -> Self {
1023 let mut ser_name = Attr::none(cx, RENAME);
1024 let mut de_name = Attr::none(cx, RENAME);
1025 let mut de_aliases = VecAttr::none(cx, RENAME);
1026 let mut skip_serializing = BoolAttr::none(cx, SKIP_SERIALIZING);
1027 let mut skip_deserializing = BoolAttr::none(cx, SKIP_DESERIALIZING);
1028 let mut skip_serializing_if = Attr::none(cx, SKIP_SERIALIZING_IF);
1029 let mut default = Attr::none(cx, DEFAULT);
1030 let mut serialize_with = Attr::none(cx, SERIALIZE_WITH);
1031 let mut deserialize_with = Attr::none(cx, DESERIALIZE_WITH);
1032 let mut ser_bound = Attr::none(cx, BOUND);
1033 let mut de_bound = Attr::none(cx, BOUND);
1034 let mut borrowed_lifetimes = Attr::none(cx, BORROW);
1035 let mut getter = Attr::none(cx, GETTER);
1036 let mut flatten = BoolAttr::none(cx, FLATTEN);
1037
1038 let ident = match &field.ident {
1039 Some(ident) => Name::from(&unraw(ident)),
1040 None => Name {
1041 value: index.to_string(),
1042 span: Span::call_site(),
1043 },
1044 };
1045
1046 if let Some(borrow_attribute) = attrs.and_then(|variant| variant.borrow.as_ref()) {
1047 if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) {
1048 if let Some(lifetimes) = &borrow_attribute.lifetimes {
1049 for lifetime in lifetimes {
1050 if !borrowable.contains(lifetime) {
1051 let msg =
1052 format!("field `{}` does not have lifetime {}", ident, lifetime);
1053 cx.error_spanned_by(field, msg);
1054 }
1055 }
1056 borrowed_lifetimes.set(&borrow_attribute.path, lifetimes.clone());
1057 } else {
1058 borrowed_lifetimes.set(&borrow_attribute.path, borrowable);
1059 }
1060 }
1061 }
1062
1063 for attr in &field.attrs {
1064 if attr.path() != SERDE {
1065 continue;
1066 }
1067
1068 if let syn::Meta::List(meta) = &attr.meta {
1069 if meta.tokens.is_empty() {
1070 continue;
1071 }
1072 }
1073
1074 if let Err(err) = attr.parse_nested_meta(|meta| {
1075 if meta.path == RENAME {
1076 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 if let Some(s) = get_lit_str(cx, ALIAS, &meta)? {
1087 de_aliases.insert(&meta.path, Name::from(&s));
1088 }
1089 } else if meta.path == DEFAULT {
1090 if meta.input.peek(Token![=]) {
1091 if let Some(path) = parse_lit_into_expr_path(cx, DEFAULT, &meta)? {
1093 default.set(&meta.path, Default::Path(path));
1094 }
1095 } else {
1096 default.set(&meta.path, Default::Default);
1098 }
1099 } else if meta.path == SKIP_SERIALIZING {
1100 skip_serializing.set_true(&meta.path);
1102 } else if meta.path == SKIP_DESERIALIZING {
1103 skip_deserializing.set_true(&meta.path);
1105 } else if meta.path == SKIP {
1106 skip_serializing.set_true(&meta.path);
1108 skip_deserializing.set_true(&meta.path);
1109 } else if meta.path == SKIP_SERIALIZING_IF {
1110 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 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 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 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 let (ser, de) = get_where_predicates(cx, &meta)?;
1144 ser_bound.set_opt(&meta.path, ser);
1145 de_bound.set_opt(&meta.path, de);
1146 } else if meta.path == BORROW {
1147 if meta.input.peek(Token![=]) {
1148 let lifetimes = parse_lit_into_lifetimes(cx, &meta)?;
1150 if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) {
1151 for lifetime in &lifetimes {
1152 if !borrowable.contains(lifetime) {
1153 let msg = format!(
1154 "field `{}` does not have lifetime {}",
1155 ident, lifetime,
1156 );
1157 cx.error_spanned_by(field, msg);
1158 }
1159 }
1160 borrowed_lifetimes.set(&meta.path, lifetimes);
1161 }
1162 } else {
1163 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 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 flatten.set_true(&meta.path);
1176 } else {
1177 let path = meta.path.to_token_stream().to_string().replace(' ', "");
1178 return Err(
1179 meta.error(format_args!("unknown serde field attribute `{}`", path))
1180 );
1181 }
1182 Ok(())
1183 }) {
1184 cx.syn_error(err);
1185 }
1186 }
1187
1188 if let Default::None = *container_default {
1192 if skip_deserializing.0.value.is_some() {
1193 default.set_if_none(Default::Default);
1194 }
1195 }
1196
1197 let mut borrowed_lifetimes = borrowed_lifetimes.get().unwrap_or_default();
1198 if !borrowed_lifetimes.is_empty() {
1199 if is_cow(&field.ty, is_str) {
1209 let mut path = syn::Path {
1210 leading_colon: None,
1211 segments: Punctuated::new(),
1212 };
1213 let span = Span::call_site();
1214 path.segments.push(Ident::new("_serde", span).into());
1215 path.segments.push(private.clone().into());
1216 path.segments.push(Ident::new("de", span).into());
1217 path.segments
1218 .push(Ident::new("borrow_cow_str", span).into());
1219 let expr = syn::ExprPath {
1220 attrs: Vec::new(),
1221 qself: None,
1222 path,
1223 };
1224 deserialize_with.set_if_none(expr);
1225 } else if is_cow(&field.ty, is_slice_u8) {
1226 let mut path = syn::Path {
1227 leading_colon: None,
1228 segments: Punctuated::new(),
1229 };
1230 let span = Span::call_site();
1231 path.segments.push(Ident::new("_serde", span).into());
1232 path.segments.push(private.clone().into());
1233 path.segments.push(Ident::new("de", span).into());
1234 path.segments
1235 .push(Ident::new("borrow_cow_bytes", span).into());
1236 let expr = syn::ExprPath {
1237 attrs: Vec::new(),
1238 qself: None,
1239 path,
1240 };
1241 deserialize_with.set_if_none(expr);
1242 }
1243 } else if is_implicitly_borrowed(&field.ty) {
1244 collect_lifetimes(&field.ty, &mut borrowed_lifetimes);
1247 }
1248
1249 Field {
1250 name: MultiName::from_attrs(ident, ser_name, de_name, Some(de_aliases)),
1251 skip_serializing: skip_serializing.get(),
1252 skip_deserializing: skip_deserializing.get(),
1253 skip_serializing_if: skip_serializing_if.get(),
1254 default: default.get().unwrap_or(Default::None),
1255 serialize_with: serialize_with.get(),
1256 deserialize_with: deserialize_with.get(),
1257 ser_bound: ser_bound.get(),
1258 de_bound: de_bound.get(),
1259 borrowed_lifetimes,
1260 getter: getter.get(),
1261 flatten: flatten.get(),
1262 transparent: false,
1263 }
1264 }
1265
1266 pub fn name(&self) -> &MultiName {
1267 &self.name
1268 }
1269
1270 pub fn aliases(&self) -> &BTreeSet<Name> {
1271 self.name.deserialize_aliases()
1272 }
1273
1274 pub fn rename_by_rules(&mut self, rules: RenameAllRules) {
1275 if !self.name.serialize_renamed {
1276 self.name.serialize.value = rules.serialize.apply_to_field(&self.name.serialize.value);
1277 }
1278 if !self.name.deserialize_renamed {
1279 self.name.deserialize.value = rules
1280 .deserialize
1281 .apply_to_field(&self.name.deserialize.value);
1282 }
1283 self.name
1284 .deserialize_aliases
1285 .insert(self.name.deserialize.clone());
1286 }
1287
1288 pub fn skip_serializing(&self) -> bool {
1289 self.skip_serializing
1290 }
1291
1292 pub fn skip_deserializing(&self) -> bool {
1293 self.skip_deserializing
1294 }
1295
1296 pub fn skip_serializing_if(&self) -> Option<&syn::ExprPath> {
1297 self.skip_serializing_if.as_ref()
1298 }
1299
1300 pub fn default(&self) -> &Default {
1301 &self.default
1302 }
1303
1304 pub fn serialize_with(&self) -> Option<&syn::ExprPath> {
1305 self.serialize_with.as_ref()
1306 }
1307
1308 pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
1309 self.deserialize_with.as_ref()
1310 }
1311
1312 pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
1313 self.ser_bound.as_ref().map(|vec| &vec[..])
1314 }
1315
1316 pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
1317 self.de_bound.as_ref().map(|vec| &vec[..])
1318 }
1319
1320 pub fn borrowed_lifetimes(&self) -> &BTreeSet<syn::Lifetime> {
1321 &self.borrowed_lifetimes
1322 }
1323
1324 pub fn getter(&self) -> Option<&syn::ExprPath> {
1325 self.getter.as_ref()
1326 }
1327
1328 pub fn flatten(&self) -> bool {
1329 self.flatten
1330 }
1331
1332 pub fn transparent(&self) -> bool {
1333 self.transparent
1334 }
1335
1336 pub fn mark_transparent(&mut self) {
1337 self.transparent = true;
1338 }
1339}
1340
1341type SerAndDe<T> = (Option<T>, Option<T>);
1342
1343fn get_ser_and_de<'c, T, F, R>(
1344 cx: &'c Ctxt,
1345 attr_name: Symbol,
1346 meta: &ParseNestedMeta,
1347 f: F,
1348) -> syn::Result<(VecAttr<'c, T>, VecAttr<'c, T>)>
1349where
1350 T: Clone,
1351 F: Fn(&Ctxt, Symbol, Symbol, &ParseNestedMeta) -> syn::Result<R>,
1352 R: Into<Option<T>>,
1353{
1354 let mut ser_meta = VecAttr::none(cx, attr_name);
1355 let mut de_meta = VecAttr::none(cx, attr_name);
1356
1357 let lookahead = meta.input.lookahead1();
1358 if lookahead.peek(Token![=]) {
1359 if let Some(both) = f(cx, attr_name, attr_name, meta)?.into() {
1360 ser_meta.insert(&meta.path, both.clone());
1361 de_meta.insert(&meta.path, both);
1362 }
1363 } else if lookahead.peek(token::Paren) {
1364 meta.parse_nested_meta(|meta| {
1365 if meta.path == SERIALIZE {
1366 if let Some(v) = f(cx, attr_name, SERIALIZE, &meta)?.into() {
1367 ser_meta.insert(&meta.path, v);
1368 }
1369 } else if meta.path == DESERIALIZE {
1370 if let Some(v) = f(cx, attr_name, DESERIALIZE, &meta)?.into() {
1371 de_meta.insert(&meta.path, v);
1372 }
1373 } else {
1374 return Err(meta.error(format_args!(
1375 "malformed {0} attribute, expected `{0}(serialize = ..., deserialize = ...)`",
1376 attr_name,
1377 )));
1378 }
1379 Ok(())
1380 })?;
1381 } else {
1382 return Err(lookahead.error());
1383 }
1384
1385 Ok((ser_meta, de_meta))
1386}
1387
1388fn get_renames(
1389 cx: &Ctxt,
1390 attr_name: Symbol,
1391 meta: &ParseNestedMeta,
1392) -> syn::Result<SerAndDe<syn::LitStr>> {
1393 let (ser, de) = get_ser_and_de(cx, attr_name, meta, get_lit_str2)?;
1394 Ok((ser.at_most_one(), de.at_most_one()))
1395}
1396
1397fn get_multiple_renames(
1398 cx: &Ctxt,
1399 meta: &ParseNestedMeta,
1400) -> syn::Result<(Option<syn::LitStr>, Vec<syn::LitStr>)> {
1401 let (ser, de) = get_ser_and_de(cx, RENAME, meta, get_lit_str2)?;
1402 Ok((ser.at_most_one(), de.get()))
1403}
1404
1405fn get_where_predicates(
1406 cx: &Ctxt,
1407 meta: &ParseNestedMeta,
1408) -> syn::Result<SerAndDe<Vec<syn::WherePredicate>>> {
1409 let (ser, de) = get_ser_and_de(cx, BOUND, meta, parse_lit_into_where)?;
1410 Ok((ser.at_most_one(), de.at_most_one()))
1411}
1412
1413fn get_lit_str(
1414 cx: &Ctxt,
1415 attr_name: Symbol,
1416 meta: &ParseNestedMeta,
1417) -> syn::Result<Option<syn::LitStr>> {
1418 get_lit_str2(cx, attr_name, attr_name, meta)
1419}
1420
1421fn get_lit_str2(
1422 cx: &Ctxt,
1423 attr_name: Symbol,
1424 meta_item_name: Symbol,
1425 meta: &ParseNestedMeta,
1426) -> syn::Result<Option<syn::LitStr>> {
1427 let expr: syn::Expr = meta.value()?.parse()?;
1428 let mut value = &expr;
1429 while let syn::Expr::Group(e) = value {
1430 value = &e.expr;
1431 }
1432 if let syn::Expr::Lit(syn::ExprLit {
1433 lit: syn::Lit::Str(lit),
1434 ..
1435 }) = value
1436 {
1437 let suffix = lit.suffix();
1438 if !suffix.is_empty() {
1439 cx.error_spanned_by(
1440 lit,
1441 format!("unexpected suffix `{}` on string literal", suffix),
1442 );
1443 }
1444 Ok(Some(lit.clone()))
1445 } else {
1446 cx.error_spanned_by(
1447 expr,
1448 format!(
1449 "expected serde {} attribute to be a string: `{} = \"...\"`",
1450 attr_name, meta_item_name
1451 ),
1452 );
1453 Ok(None)
1454 }
1455}
1456
1457fn parse_lit_into_path(
1458 cx: &Ctxt,
1459 attr_name: Symbol,
1460 meta: &ParseNestedMeta,
1461) -> syn::Result<Option<syn::Path>> {
1462 let string = match get_lit_str(cx, attr_name, meta)? {
1463 Some(string) => string,
1464 None => return Ok(None),
1465 };
1466
1467 Ok(match string.parse() {
1468 Ok(path) => Some(path),
1469 Err(_) => {
1470 cx.error_spanned_by(
1471 &string,
1472 format!("failed to parse path: {:?}", string.value()),
1473 );
1474 None
1475 }
1476 })
1477}
1478
1479fn parse_lit_into_expr_path(
1480 cx: &Ctxt,
1481 attr_name: Symbol,
1482 meta: &ParseNestedMeta,
1483) -> syn::Result<Option<syn::ExprPath>> {
1484 let string = match get_lit_str(cx, attr_name, meta)? {
1485 Some(string) => string,
1486 None => return Ok(None),
1487 };
1488
1489 Ok(match string.parse() {
1490 Ok(expr) => Some(expr),
1491 Err(_) => {
1492 cx.error_spanned_by(
1493 &string,
1494 format!("failed to parse path: {:?}", string.value()),
1495 );
1496 None
1497 }
1498 })
1499}
1500
1501fn parse_lit_into_where(
1502 cx: &Ctxt,
1503 attr_name: Symbol,
1504 meta_item_name: Symbol,
1505 meta: &ParseNestedMeta,
1506) -> syn::Result<Vec<syn::WherePredicate>> {
1507 let string = match get_lit_str2(cx, attr_name, meta_item_name, meta)? {
1508 Some(string) => string,
1509 None => return Ok(Vec::new()),
1510 };
1511
1512 Ok(
1513 match string.parse_with(Punctuated::<syn::WherePredicate, Token![,]>::parse_terminated) {
1514 Ok(predicates) => Vec::from_iter(predicates),
1515 Err(err) => {
1516 cx.error_spanned_by(string, err);
1517 Vec::new()
1518 }
1519 },
1520 )
1521}
1522
1523fn parse_lit_into_ty(
1524 cx: &Ctxt,
1525 attr_name: Symbol,
1526 meta: &ParseNestedMeta,
1527) -> syn::Result<Option<syn::Type>> {
1528 let string = match get_lit_str(cx, attr_name, meta)? {
1529 Some(string) => string,
1530 None => return Ok(None),
1531 };
1532
1533 Ok(match string.parse() {
1534 Ok(ty) => Some(ty),
1535 Err(_) => {
1536 cx.error_spanned_by(
1537 &string,
1538 format!("failed to parse type: {} = {:?}", attr_name, string.value()),
1539 );
1540 None
1541 }
1542 })
1543}
1544
1545fn parse_lit_into_lifetimes(
1548 cx: &Ctxt,
1549 meta: &ParseNestedMeta,
1550) -> syn::Result<BTreeSet<syn::Lifetime>> {
1551 let string = match get_lit_str(cx, BORROW, meta)? {
1552 Some(string) => string,
1553 None => return Ok(BTreeSet::new()),
1554 };
1555
1556 if let Ok(lifetimes) = string.parse_with(|input: ParseStream| {
1557 let mut set = BTreeSet::new();
1558 while !input.is_empty() {
1559 let lifetime: Lifetime = input.parse()?;
1560 if !set.insert(lifetime.clone()) {
1561 cx.error_spanned_by(
1562 &string,
1563 format!("duplicate borrowed lifetime `{}`", lifetime),
1564 );
1565 }
1566 if input.is_empty() {
1567 break;
1568 }
1569 input.parse::<Token![+]>()?;
1570 }
1571 Ok(set)
1572 }) {
1573 if lifetimes.is_empty() {
1574 cx.error_spanned_by(string, "at least one lifetime must be borrowed");
1575 }
1576 return Ok(lifetimes);
1577 }
1578
1579 cx.error_spanned_by(
1580 &string,
1581 format!("failed to parse borrowed lifetimes: {:?}", string.value()),
1582 );
1583 Ok(BTreeSet::new())
1584}
1585
1586fn is_implicitly_borrowed(ty: &syn::Type) -> bool {
1587 is_implicitly_borrowed_reference(ty) || is_option(ty, is_implicitly_borrowed_reference)
1588}
1589
1590fn is_implicitly_borrowed_reference(ty: &syn::Type) -> bool {
1591 is_reference(ty, is_str) || is_reference(ty, is_slice_u8)
1592}
1593
1594fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
1617 let path = match ungroup(ty) {
1618 syn::Type::Path(ty) => &ty.path,
1619 _ => {
1620 return false;
1621 }
1622 };
1623 let seg = match path.segments.last() {
1624 Some(seg) => seg,
1625 None => {
1626 return false;
1627 }
1628 };
1629 let args = match &seg.arguments {
1630 syn::PathArguments::AngleBracketed(bracketed) => &bracketed.args,
1631 _ => {
1632 return false;
1633 }
1634 };
1635 seg.ident == "Cow"
1636 && args.len() == 2
1637 && match (&args[0], &args[1]) {
1638 (syn::GenericArgument::Lifetime(_), syn::GenericArgument::Type(arg)) => elem(arg),
1639 _ => false,
1640 }
1641}
1642
1643fn is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
1644 let path = match ungroup(ty) {
1645 syn::Type::Path(ty) => &ty.path,
1646 _ => {
1647 return false;
1648 }
1649 };
1650 let seg = match path.segments.last() {
1651 Some(seg) => seg,
1652 None => {
1653 return false;
1654 }
1655 };
1656 let args = match &seg.arguments {
1657 syn::PathArguments::AngleBracketed(bracketed) => &bracketed.args,
1658 _ => {
1659 return false;
1660 }
1661 };
1662 seg.ident == "Option"
1663 && args.len() == 1
1664 && match &args[0] {
1665 syn::GenericArgument::Type(arg) => elem(arg),
1666 _ => false,
1667 }
1668}
1669
1670fn is_reference(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
1691 match ungroup(ty) {
1692 syn::Type::Reference(ty) => ty.mutability.is_none() && elem(&ty.elem),
1693 _ => false,
1694 }
1695}
1696
1697fn is_str(ty: &syn::Type) -> bool {
1698 is_primitive_type(ty, "str")
1699}
1700
1701fn is_slice_u8(ty: &syn::Type) -> bool {
1702 match ungroup(ty) {
1703 syn::Type::Slice(ty) => is_primitive_type(&ty.elem, "u8"),
1704 _ => false,
1705 }
1706}
1707
1708fn is_primitive_type(ty: &syn::Type, primitive: &str) -> bool {
1709 match ungroup(ty) {
1710 syn::Type::Path(ty) => ty.qself.is_none() && is_primitive_path(&ty.path, primitive),
1711 _ => false,
1712 }
1713}
1714
1715fn is_primitive_path(path: &syn::Path, primitive: &str) -> bool {
1716 path.leading_colon.is_none()
1717 && path.segments.len() == 1
1718 && path.segments[0].ident == primitive
1719 && path.segments[0].arguments.is_empty()
1720}
1721
1722fn borrowable_lifetimes(
1730 cx: &Ctxt,
1731 name: &Name,
1732 field: &syn::Field,
1733) -> Result<BTreeSet<syn::Lifetime>, ()> {
1734 let mut lifetimes = BTreeSet::new();
1735 collect_lifetimes(&field.ty, &mut lifetimes);
1736 if lifetimes.is_empty() {
1737 let msg = format!("field `{}` has no lifetimes to borrow", name);
1738 cx.error_spanned_by(field, msg);
1739 Err(())
1740 } else {
1741 Ok(lifetimes)
1742 }
1743}
1744
1745fn collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet<syn::Lifetime>) {
1746 match ty {
1747 #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
1748 syn::Type::Slice(ty) => {
1749 collect_lifetimes(&ty.elem, out);
1750 }
1751 syn::Type::Array(ty) => {
1752 collect_lifetimes(&ty.elem, out);
1753 }
1754 syn::Type::Ptr(ty) => {
1755 collect_lifetimes(&ty.elem, out);
1756 }
1757 syn::Type::Reference(ty) => {
1758 out.extend(ty.lifetime.iter().cloned());
1759 collect_lifetimes(&ty.elem, out);
1760 }
1761 syn::Type::Tuple(ty) => {
1762 for elem in &ty.elems {
1763 collect_lifetimes(elem, out);
1764 }
1765 }
1766 syn::Type::Path(ty) => {
1767 if let Some(qself) = &ty.qself {
1768 collect_lifetimes(&qself.ty, out);
1769 }
1770 for seg in &ty.path.segments {
1771 if let syn::PathArguments::AngleBracketed(bracketed) = &seg.arguments {
1772 for arg in &bracketed.args {
1773 match arg {
1774 syn::GenericArgument::Lifetime(lifetime) => {
1775 out.insert(lifetime.clone());
1776 }
1777 syn::GenericArgument::Type(ty) => {
1778 collect_lifetimes(ty, out);
1779 }
1780 syn::GenericArgument::AssocType(binding) => {
1781 collect_lifetimes(&binding.ty, out);
1782 }
1783 syn::GenericArgument::Const(_)
1784 | syn::GenericArgument::AssocConst(_)
1785 | syn::GenericArgument::Constraint(_)
1786 | _ => {}
1787 }
1788 }
1789 }
1790 }
1791 }
1792 syn::Type::Paren(ty) => {
1793 collect_lifetimes(&ty.elem, out);
1794 }
1795 syn::Type::Group(ty) => {
1796 collect_lifetimes(&ty.elem, out);
1797 }
1798 syn::Type::Macro(ty) => {
1799 collect_lifetimes_from_tokens(ty.mac.tokens.clone(), out);
1800 }
1801 syn::Type::BareFn(_)
1802 | syn::Type::Never(_)
1803 | syn::Type::TraitObject(_)
1804 | syn::Type::ImplTrait(_)
1805 | syn::Type::Infer(_)
1806 | syn::Type::Verbatim(_) => {}
1807
1808 _ => {}
1809 }
1810}
1811
1812fn collect_lifetimes_from_tokens(tokens: TokenStream, out: &mut BTreeSet<syn::Lifetime>) {
1813 let mut iter = tokens.into_iter();
1814 while let Some(tt) = iter.next() {
1815 match &tt {
1816 TokenTree::Punct(op) if op.as_char() == '\'' && op.spacing() == Spacing::Joint => {
1817 if let Some(TokenTree::Ident(ident)) = iter.next() {
1818 out.insert(syn::Lifetime {
1819 apostrophe: op.span(),
1820 ident,
1821 });
1822 }
1823 }
1824 TokenTree::Group(group) => {
1825 let tokens = group.stream();
1826 collect_lifetimes_from_tokens(tokens, out);
1827 }
1828 _ => {}
1829 }
1830 }
1831}