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