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