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