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