]> git.proxmox.com Git - rustc.git/blob - src/vendor/serde_derive_internals/src/attr.rs
New upstream version 1.21.0+dfsg1
[rustc.git] / src / vendor / serde_derive_internals / src / attr.rs
1 // Copyright 2017 Serde Developers
2 //
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
8
9 use Ctxt;
10 use syn;
11 use syn::MetaItem::{List, NameValue, Word};
12 use syn::NestedMetaItem::{Literal, MetaItem};
13 use synom::IResult;
14 use std::collections::BTreeSet;
15 use std::str::FromStr;
16
17 // This module handles parsing of `#[serde(...)]` attributes. The entrypoints
18 // are `attr::Container::from_ast`, `attr::Variant::from_ast`, and
19 // `attr::Field::from_ast`. Each returns an instance of the corresponding
20 // struct. Note that none of them return a Result. Unrecognized, malformed, or
21 // duplicated attributes result in a span_err but otherwise are ignored. The
22 // user will see errors simultaneously for all bad attributes in the crate
23 // rather than just the first.
24
25 pub use case::RenameRule;
26
27 struct Attr<'c, T> {
28 cx: &'c Ctxt,
29 name: &'static str,
30 value: Option<T>,
31 }
32
33 impl<'c, T> Attr<'c, T> {
34 fn none(cx: &'c Ctxt, name: &'static str) -> Self {
35 Attr {
36 cx: cx,
37 name: name,
38 value: None,
39 }
40 }
41
42 fn set(&mut self, value: T) {
43 if self.value.is_some() {
44 self.cx
45 .error(format!("duplicate serde attribute `{}`", self.name));
46 } else {
47 self.value = Some(value);
48 }
49 }
50
51 fn set_opt(&mut self, value: Option<T>) {
52 if let Some(value) = value {
53 self.set(value);
54 }
55 }
56
57 fn set_if_none(&mut self, value: T) {
58 if self.value.is_none() {
59 self.value = Some(value);
60 }
61 }
62
63 fn get(self) -> Option<T> {
64 self.value
65 }
66 }
67
68 struct BoolAttr<'c>(Attr<'c, ()>);
69
70 impl<'c> BoolAttr<'c> {
71 fn none(cx: &'c Ctxt, name: &'static str) -> Self {
72 BoolAttr(Attr::none(cx, name))
73 }
74
75 fn set_true(&mut self) {
76 self.0.set(());
77 }
78
79 fn get(&self) -> bool {
80 self.0.value.is_some()
81 }
82 }
83
84 #[derive(Debug)]
85 pub struct Name {
86 serialize: String,
87 deserialize: String,
88 }
89
90 impl Name {
91 /// Return the container name for the container when serializing.
92 pub fn serialize_name(&self) -> String {
93 self.serialize.clone()
94 }
95
96 /// Return the container name for the container when deserializing.
97 pub fn deserialize_name(&self) -> String {
98 self.deserialize.clone()
99 }
100 }
101
102 /// Represents container (e.g. struct) attribute information
103 #[derive(Debug)]
104 pub struct Container {
105 name: Name,
106 deny_unknown_fields: bool,
107 default: Default,
108 rename_all: RenameRule,
109 ser_bound: Option<Vec<syn::WherePredicate>>,
110 de_bound: Option<Vec<syn::WherePredicate>>,
111 tag: EnumTag,
112 from_type: Option<syn::Ty>,
113 into_type: Option<syn::Ty>,
114 remote: Option<syn::Path>,
115 identifier: Identifier,
116 }
117
118 /// Styles of representing an enum.
119 #[derive(Debug)]
120 pub enum EnumTag {
121 /// The default.
122 ///
123 /// ```json
124 /// {"variant1": {"key1": "value1", "key2": "value2"}}
125 /// ```
126 External,
127
128 /// `#[serde(tag = "type")]`
129 ///
130 /// ```json
131 /// {"type": "variant1", "key1": "value1", "key2": "value2"}
132 /// ```
133 Internal { tag: String },
134
135 /// `#[serde(tag = "t", content = "c")]`
136 ///
137 /// ```json
138 /// {"t": "variant1", "c": {"key1": "value1", "key2": "value2"}}
139 /// ```
140 Adjacent { tag: String, content: String },
141
142 /// `#[serde(untagged)]`
143 ///
144 /// ```json
145 /// {"key1": "value1", "key2": "value2"}
146 /// ```
147 None,
148 }
149
150 /// Whether this enum represents the fields of a struct or the variants of an
151 /// enum.
152 #[derive(Copy, Clone, Debug)]
153 pub enum Identifier {
154 /// It does not.
155 No,
156
157 /// This enum represents the fields of a struct. All of the variants must be
158 /// unit variants, except possibly one which is annotated with
159 /// `#[serde(other)]` and is a newtype variant.
160 Field,
161
162 /// This enum represents the variants of an enum. All of the variants must
163 /// be unit variants.
164 Variant,
165 }
166
167 impl Container {
168 /// Extract out the `#[serde(...)]` attributes from an item.
169 pub fn from_ast(cx: &Ctxt, item: &syn::DeriveInput) -> Self {
170 let mut ser_name = Attr::none(cx, "rename");
171 let mut de_name = Attr::none(cx, "rename");
172 let mut deny_unknown_fields = BoolAttr::none(cx, "deny_unknown_fields");
173 let mut default = Attr::none(cx, "default");
174 let mut rename_all = Attr::none(cx, "rename_all");
175 let mut ser_bound = Attr::none(cx, "bound");
176 let mut de_bound = Attr::none(cx, "bound");
177 let mut untagged = BoolAttr::none(cx, "untagged");
178 let mut internal_tag = Attr::none(cx, "tag");
179 let mut content = Attr::none(cx, "content");
180 let mut from_type = Attr::none(cx, "from");
181 let mut into_type = Attr::none(cx, "into");
182 let mut remote = Attr::none(cx, "remote");
183 let mut field_identifier = BoolAttr::none(cx, "field_identifier");
184 let mut variant_identifier = BoolAttr::none(cx, "variant_identifier");
185
186 for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) {
187 for meta_item in meta_items {
188 match meta_item {
189 // Parse `#[serde(rename = "foo")]`
190 MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
191 if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
192 ser_name.set(s.clone());
193 de_name.set(s);
194 }
195 }
196
197 // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
198 MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
199 if let Ok((ser, de)) = get_renames(cx, meta_items) {
200 ser_name.set_opt(ser);
201 de_name.set_opt(de);
202 }
203 }
204
205 // Parse `#[serde(rename_all = "foo")]`
206 MetaItem(NameValue(ref name, ref lit)) if name == "rename_all" => {
207 if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
208 match RenameRule::from_str(&s) {
209 Ok(rename_rule) => rename_all.set(rename_rule),
210 Err(()) => {
211 cx.error(format!("unknown rename rule for #[serde(rename_all \
212 = {:?})]",
213 s))
214 }
215 }
216 }
217 }
218
219 // Parse `#[serde(deny_unknown_fields)]`
220 MetaItem(Word(ref name)) if name == "deny_unknown_fields" => {
221 deny_unknown_fields.set_true();
222 }
223
224 // Parse `#[serde(default)]`
225 MetaItem(Word(ref name)) if name == "default" => {
226 match item.body {
227 syn::Body::Struct(syn::VariantData::Struct(_)) => {
228 default.set(Default::Default);
229 }
230 _ => {
231 cx.error(
232 "#[serde(default)] can only be used on structs \
233 with named fields",
234 )
235 }
236 }
237 }
238
239 // Parse `#[serde(default = "...")]`
240 MetaItem(NameValue(ref name, ref lit)) if name == "default" => {
241 if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
242 match item.body {
243 syn::Body::Struct(syn::VariantData::Struct(_)) => {
244 default.set(Default::Path(path));
245 }
246 _ => {
247 cx.error(
248 "#[serde(default = \"...\")] can only be used \
249 on structs with named fields",
250 )
251 }
252 }
253 }
254 }
255
256 // Parse `#[serde(bound = "D: Serialize")]`
257 MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
258 if let Ok(where_predicates) =
259 parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) {
260 ser_bound.set(where_predicates.clone());
261 de_bound.set(where_predicates);
262 }
263 }
264
265 // Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
266 MetaItem(List(ref name, ref meta_items)) if name == "bound" => {
267 if let Ok((ser, de)) = get_where_predicates(cx, meta_items) {
268 ser_bound.set_opt(ser);
269 de_bound.set_opt(de);
270 }
271 }
272
273 // Parse `#[serde(untagged)]`
274 MetaItem(Word(ref name)) if name == "untagged" => {
275 match item.body {
276 syn::Body::Enum(_) => {
277 untagged.set_true();
278 }
279 syn::Body::Struct(_) => {
280 cx.error("#[serde(untagged)] can only be used on enums")
281 }
282 }
283 }
284
285 // Parse `#[serde(tag = "type")]`
286 MetaItem(NameValue(ref name, ref lit)) if name == "tag" => {
287 if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
288 match item.body {
289 syn::Body::Enum(_) => {
290 internal_tag.set(s);
291 }
292 syn::Body::Struct(_) => {
293 cx.error("#[serde(tag = \"...\")] can only be used on enums")
294 }
295 }
296 }
297 }
298
299 // Parse `#[serde(content = "c")]`
300 MetaItem(NameValue(ref name, ref lit)) if name == "content" => {
301 if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
302 match item.body {
303 syn::Body::Enum(_) => {
304 content.set(s);
305 }
306 syn::Body::Struct(_) => {
307 cx.error(
308 "#[serde(content = \"...\")] can only be used on \
309 enums",
310 )
311 }
312 }
313 }
314 }
315
316 // Parse `#[serde(from = "Type")]
317 MetaItem(NameValue(ref name, ref lit)) if name == "from" => {
318 if let Ok(from_ty) = parse_lit_into_ty(cx, name.as_ref(), lit) {
319 from_type.set_opt(Some(from_ty));
320 }
321 }
322
323 // Parse `#[serde(into = "Type")]
324 MetaItem(NameValue(ref name, ref lit)) if name == "into" => {
325 if let Ok(into_ty) = parse_lit_into_ty(cx, name.as_ref(), lit) {
326 into_type.set_opt(Some(into_ty));
327 }
328 }
329
330 // Parse `#[serde(remote = "...")]`
331 MetaItem(NameValue(ref name, ref lit)) if name == "remote" => {
332 if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
333 remote.set(path);
334 }
335 }
336
337 // Parse `#[serde(field_identifier)]`
338 MetaItem(Word(ref name)) if name == "field_identifier" => {
339 field_identifier.set_true();
340 }
341
342 // Parse `#[serde(variant_identifier)]`
343 MetaItem(Word(ref name)) if name == "variant_identifier" => {
344 variant_identifier.set_true();
345 }
346
347 MetaItem(ref meta_item) => {
348 cx.error(format!("unknown serde container attribute `{}`",
349 meta_item.name()));
350 }
351
352 Literal(_) => {
353 cx.error("unexpected literal in serde container attribute");
354 }
355 }
356 }
357 }
358
359 Container {
360 name: Name {
361 serialize: ser_name.get().unwrap_or_else(|| item.ident.to_string()),
362 deserialize: de_name.get().unwrap_or_else(|| item.ident.to_string()),
363 },
364 deny_unknown_fields: deny_unknown_fields.get(),
365 default: default.get().unwrap_or(Default::None),
366 rename_all: rename_all.get().unwrap_or(RenameRule::None),
367 ser_bound: ser_bound.get(),
368 de_bound: de_bound.get(),
369 tag: decide_tag(cx, item, untagged, internal_tag, content),
370 from_type: from_type.get(),
371 into_type: into_type.get(),
372 remote: remote.get(),
373 identifier: decide_identifier(cx, item, field_identifier, variant_identifier),
374 }
375 }
376
377 pub fn name(&self) -> &Name {
378 &self.name
379 }
380
381 pub fn rename_all(&self) -> &RenameRule {
382 &self.rename_all
383 }
384
385 pub fn deny_unknown_fields(&self) -> bool {
386 self.deny_unknown_fields
387 }
388
389 pub fn default(&self) -> &Default {
390 &self.default
391 }
392
393 pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
394 self.ser_bound.as_ref().map(|vec| &vec[..])
395 }
396
397 pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
398 self.de_bound.as_ref().map(|vec| &vec[..])
399 }
400
401 pub fn tag(&self) -> &EnumTag {
402 &self.tag
403 }
404
405 pub fn from_type(&self) -> Option<&syn::Ty> {
406 self.from_type.as_ref()
407 }
408
409 pub fn into_type(&self) -> Option<&syn::Ty> {
410 self.into_type.as_ref()
411 }
412
413 pub fn remote(&self) -> Option<&syn::Path> {
414 self.remote.as_ref()
415 }
416
417 pub fn identifier(&self) -> Identifier {
418 self.identifier
419 }
420 }
421
422 fn decide_tag(
423 cx: &Ctxt,
424 item: &syn::DeriveInput,
425 untagged: BoolAttr,
426 internal_tag: Attr<String>,
427 content: Attr<String>,
428 ) -> EnumTag {
429 match (untagged.get(), internal_tag.get(), content.get()) {
430 (false, None, None) => EnumTag::External,
431 (true, None, None) => EnumTag::None,
432 (false, Some(tag), None) => {
433 // Check that there are no tuple variants.
434 if let syn::Body::Enum(ref variants) = item.body {
435 for variant in variants {
436 match variant.data {
437 syn::VariantData::Struct(_) |
438 syn::VariantData::Unit => {}
439 syn::VariantData::Tuple(ref fields) => {
440 if fields.len() != 1 {
441 cx.error(
442 "#[serde(tag = \"...\")] cannot be used with tuple \
443 variants",
444 );
445 break;
446 }
447 }
448 }
449 }
450 }
451 EnumTag::Internal { tag: tag }
452 }
453 (true, Some(_), None) => {
454 cx.error("enum cannot be both untagged and internally tagged");
455 EnumTag::External // doesn't matter, will error
456 }
457 (false, None, Some(_)) => {
458 cx.error("#[serde(tag = \"...\", content = \"...\")] must be used together",);
459 EnumTag::External
460 }
461 (true, None, Some(_)) => {
462 cx.error("untagged enum cannot have #[serde(content = \"...\")]");
463 EnumTag::External
464 }
465 (false, Some(tag), Some(content)) => {
466 EnumTag::Adjacent {
467 tag: tag,
468 content: content,
469 }
470 }
471 (true, Some(_), Some(_)) => {
472 cx.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]",);
473 EnumTag::External
474 }
475 }
476 }
477
478 fn decide_identifier(
479 cx: &Ctxt,
480 item: &syn::DeriveInput,
481 field_identifier: BoolAttr,
482 variant_identifier: BoolAttr,
483 ) -> Identifier {
484 match (&item.body, field_identifier.get(), variant_identifier.get()) {
485 (_, false, false) => Identifier::No,
486 (_, true, true) => {
487 cx.error("`field_identifier` and `variant_identifier` cannot both be set",);
488 Identifier::No
489 }
490 (&syn::Body::Struct(_), true, false) => {
491 cx.error("`field_identifier` can only be used on an enum");
492 Identifier::No
493 }
494 (&syn::Body::Struct(_), false, true) => {
495 cx.error("`variant_identifier` can only be used on an enum");
496 Identifier::No
497 }
498 (&syn::Body::Enum(_), true, false) => Identifier::Field,
499 (&syn::Body::Enum(_), false, true) => Identifier::Variant,
500 }
501 }
502
503 /// Represents variant attribute information
504 #[derive(Debug)]
505 pub struct Variant {
506 name: Name,
507 ser_renamed: bool,
508 de_renamed: bool,
509 rename_all: RenameRule,
510 skip_deserializing: bool,
511 skip_serializing: bool,
512 other: bool,
513 }
514
515 impl Variant {
516 pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self {
517 let mut ser_name = Attr::none(cx, "rename");
518 let mut de_name = Attr::none(cx, "rename");
519 let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
520 let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
521 let mut rename_all = Attr::none(cx, "rename_all");
522 let mut other = BoolAttr::none(cx, "other");
523
524 for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) {
525 for meta_item in meta_items {
526 match meta_item {
527 // Parse `#[serde(rename = "foo")]`
528 MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
529 if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
530 ser_name.set(s.clone());
531 de_name.set(s);
532 }
533 }
534
535 // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
536 MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
537 if let Ok((ser, de)) = get_renames(cx, meta_items) {
538 ser_name.set_opt(ser);
539 de_name.set_opt(de);
540 }
541 }
542
543 // Parse `#[serde(rename_all = "foo")]`
544 MetaItem(NameValue(ref name, ref lit)) if name == "rename_all" => {
545 if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
546 match RenameRule::from_str(&s) {
547 Ok(rename_rule) => rename_all.set(rename_rule),
548 Err(()) => {
549 cx.error(format!("unknown rename rule for #[serde(rename_all \
550 = {:?})]",
551 s))
552 }
553 }
554 }
555 }
556
557 // Parse `#[serde(skip_deserializing)]`
558 MetaItem(Word(ref name)) if name == "skip_deserializing" => {
559 skip_deserializing.set_true();
560 }
561
562 // Parse `#[serde(skip_serializing)]`
563 MetaItem(Word(ref name)) if name == "skip_serializing" => {
564 skip_serializing.set_true();
565 }
566
567 // Parse `#[serde(other)]`
568 MetaItem(Word(ref name)) if name == "other" => {
569 other.set_true();
570 }
571
572 MetaItem(ref meta_item) => {
573 cx.error(format!("unknown serde variant attribute `{}`", meta_item.name()));
574 }
575
576 Literal(_) => {
577 cx.error("unexpected literal in serde variant attribute");
578 }
579 }
580 }
581 }
582
583 let ser_name = ser_name.get();
584 let ser_renamed = ser_name.is_some();
585 let de_name = de_name.get();
586 let de_renamed = de_name.is_some();
587 Variant {
588 name: Name {
589 serialize: ser_name.unwrap_or_else(|| variant.ident.to_string()),
590 deserialize: de_name.unwrap_or_else(|| variant.ident.to_string()),
591 },
592 ser_renamed: ser_renamed,
593 de_renamed: de_renamed,
594 rename_all: rename_all.get().unwrap_or(RenameRule::None),
595 skip_deserializing: skip_deserializing.get(),
596 skip_serializing: skip_serializing.get(),
597 other: other.get(),
598 }
599 }
600
601 pub fn name(&self) -> &Name {
602 &self.name
603 }
604
605 pub fn rename_by_rule(&mut self, rule: &RenameRule) {
606 if !self.ser_renamed {
607 self.name.serialize = rule.apply_to_variant(&self.name.serialize);
608 }
609 if !self.de_renamed {
610 self.name.deserialize = rule.apply_to_variant(&self.name.deserialize);
611 }
612 }
613
614 pub fn rename_all(&self) -> &RenameRule {
615 &self.rename_all
616 }
617
618 pub fn skip_deserializing(&self) -> bool {
619 self.skip_deserializing
620 }
621
622 pub fn skip_serializing(&self) -> bool {
623 self.skip_serializing
624 }
625
626 pub fn other(&self) -> bool {
627 self.other
628 }
629 }
630
631 /// Represents field attribute information
632 #[derive(Debug)]
633 pub struct Field {
634 name: Name,
635 ser_renamed: bool,
636 de_renamed: bool,
637 skip_serializing: bool,
638 skip_deserializing: bool,
639 skip_serializing_if: Option<syn::Path>,
640 default: Default,
641 serialize_with: Option<syn::Path>,
642 deserialize_with: Option<syn::Path>,
643 ser_bound: Option<Vec<syn::WherePredicate>>,
644 de_bound: Option<Vec<syn::WherePredicate>>,
645 borrowed_lifetimes: BTreeSet<syn::Lifetime>,
646 getter: Option<syn::Path>,
647 }
648
649 /// Represents the default to use for a field when deserializing.
650 #[derive(Debug, PartialEq)]
651 pub enum Default {
652 /// Field must always be specified because it does not have a default.
653 None,
654 /// The default is given by `std::default::Default::default()`.
655 Default,
656 /// The default is given by this function.
657 Path(syn::Path),
658 }
659
660 impl Field {
661 /// Extract out the `#[serde(...)]` attributes from a struct field.
662 pub fn from_ast(cx: &Ctxt, index: usize, field: &syn::Field) -> Self {
663 let mut ser_name = Attr::none(cx, "rename");
664 let mut de_name = Attr::none(cx, "rename");
665 let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
666 let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
667 let mut skip_serializing_if = Attr::none(cx, "skip_serializing_if");
668 let mut default = Attr::none(cx, "default");
669 let mut serialize_with = Attr::none(cx, "serialize_with");
670 let mut deserialize_with = Attr::none(cx, "deserialize_with");
671 let mut ser_bound = Attr::none(cx, "bound");
672 let mut de_bound = Attr::none(cx, "bound");
673 let mut borrowed_lifetimes = Attr::none(cx, "borrow");
674 let mut getter = Attr::none(cx, "getter");
675
676 let ident = match field.ident {
677 Some(ref ident) => ident.to_string(),
678 None => index.to_string(),
679 };
680
681 for meta_items in field.attrs.iter().filter_map(get_serde_meta_items) {
682 for meta_item in meta_items {
683 match meta_item {
684 // Parse `#[serde(rename = "foo")]`
685 MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
686 if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
687 ser_name.set(s.clone());
688 de_name.set(s);
689 }
690 }
691
692 // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
693 MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
694 if let Ok((ser, de)) = get_renames(cx, meta_items) {
695 ser_name.set_opt(ser);
696 de_name.set_opt(de);
697 }
698 }
699
700 // Parse `#[serde(default)]`
701 MetaItem(Word(ref name)) if name == "default" => {
702 default.set(Default::Default);
703 }
704
705 // Parse `#[serde(default = "...")]`
706 MetaItem(NameValue(ref name, ref lit)) if name == "default" => {
707 if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
708 default.set(Default::Path(path));
709 }
710 }
711
712 // Parse `#[serde(skip_serializing)]`
713 MetaItem(Word(ref name)) if name == "skip_serializing" => {
714 skip_serializing.set_true();
715 }
716
717 // Parse `#[serde(skip_deserializing)]`
718 MetaItem(Word(ref name)) if name == "skip_deserializing" => {
719 skip_deserializing.set_true();
720 }
721
722 // Parse `#[serde(skip)]`
723 MetaItem(Word(ref name)) if name == "skip" => {
724 skip_serializing.set_true();
725 skip_deserializing.set_true();
726 },
727
728 // Parse `#[serde(skip_serializing_if = "...")]`
729 MetaItem(NameValue(ref name, ref lit)) if name == "skip_serializing_if" => {
730 if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
731 skip_serializing_if.set(path);
732 }
733 }
734
735 // Parse `#[serde(serialize_with = "...")]`
736 MetaItem(NameValue(ref name, ref lit)) if name == "serialize_with" => {
737 if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
738 serialize_with.set(path);
739 }
740 }
741
742 // Parse `#[serde(deserialize_with = "...")]`
743 MetaItem(NameValue(ref name, ref lit)) if name == "deserialize_with" => {
744 if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
745 deserialize_with.set(path);
746 }
747 }
748
749 // Parse `#[serde(with = "...")]`
750 MetaItem(NameValue(ref name, ref lit)) if name == "with" => {
751 if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
752 let mut ser_path = path.clone();
753 ser_path.segments.push("serialize".into());
754 serialize_with.set(ser_path);
755 let mut de_path = path;
756 de_path.segments.push("deserialize".into());
757 deserialize_with.set(de_path);
758 }
759 }
760
761 // Parse `#[serde(bound = "D: Serialize")]`
762 MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
763 if let Ok(where_predicates) =
764 parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) {
765 ser_bound.set(where_predicates.clone());
766 de_bound.set(where_predicates);
767 }
768 }
769
770 // Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
771 MetaItem(List(ref name, ref meta_items)) if name == "bound" => {
772 if let Ok((ser, de)) = get_where_predicates(cx, meta_items) {
773 ser_bound.set_opt(ser);
774 de_bound.set_opt(de);
775 }
776 }
777
778 // Parse `#[serde(borrow)]`
779 MetaItem(Word(ref name)) if name == "borrow" => {
780 if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) {
781 borrowed_lifetimes.set(borrowable);
782 }
783 }
784
785 // Parse `#[serde(borrow = "'a + 'b")]`
786 MetaItem(NameValue(ref name, ref lit)) if name == "borrow" => {
787 if let Ok(lifetimes) = parse_lit_into_lifetimes(cx, name.as_ref(), lit) {
788 if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) {
789 for lifetime in &lifetimes {
790 if !borrowable.contains(lifetime) {
791 cx.error(
792 format!(
793 "field `{}` does not have lifetime {}",
794 ident,
795 lifetime.ident
796 ),
797 );
798 }
799 }
800 borrowed_lifetimes.set(lifetimes);
801 }
802 }
803 }
804
805 // Parse `#[serde(getter = "...")]`
806 MetaItem(NameValue(ref name, ref lit)) if name == "getter" => {
807 if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
808 getter.set(path);
809 }
810 }
811
812 MetaItem(ref meta_item) => {
813 cx.error(format!("unknown serde field attribute `{}`", meta_item.name()),);
814 }
815
816 Literal(_) => {
817 cx.error("unexpected literal in serde field attribute");
818 }
819 }
820 }
821 }
822
823 // Is skip_deserializing, initialize the field to Default::default()
824 // unless a different default is specified by `#[serde(default = "...")]`
825 if skip_deserializing.0.value.is_some() {
826 default.set_if_none(Default::Default);
827 }
828
829 let mut borrowed_lifetimes = borrowed_lifetimes.get().unwrap_or_default();
830 if !borrowed_lifetimes.is_empty() {
831 // Cow<str> and Cow<[u8]> never borrow by default:
832 //
833 // impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
834 //
835 // A #[serde(borrow)] attribute enables borrowing that corresponds
836 // roughly to these impls:
837 //
838 // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, str>
839 // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]>
840 if is_cow(&field.ty, "str") {
841 let path = syn::parse_path("_serde::private::de::borrow_cow_str").unwrap();
842 deserialize_with.set_if_none(path);
843 } else if is_cow(&field.ty, "[u8]") {
844 let path = syn::parse_path("_serde::private::de::borrow_cow_bytes").unwrap();
845 deserialize_with.set_if_none(path);
846 }
847 } else if is_rptr(&field.ty, "str") || is_rptr(&field.ty, "[u8]") {
848 // Types &str and &[u8] are always implicitly borrowed. No need for
849 // a #[serde(borrow)].
850 borrowed_lifetimes = borrowable_lifetimes(cx, &ident, &field.ty).unwrap();
851 }
852
853 let ser_name = ser_name.get();
854 let ser_renamed = ser_name.is_some();
855 let de_name = de_name.get();
856 let de_renamed = de_name.is_some();
857 Field {
858 name: Name {
859 serialize: ser_name.unwrap_or_else(|| ident.clone()),
860 deserialize: de_name.unwrap_or(ident),
861 },
862 ser_renamed: ser_renamed,
863 de_renamed: de_renamed,
864 skip_serializing: skip_serializing.get(),
865 skip_deserializing: skip_deserializing.get(),
866 skip_serializing_if: skip_serializing_if.get(),
867 default: default.get().unwrap_or(Default::None),
868 serialize_with: serialize_with.get(),
869 deserialize_with: deserialize_with.get(),
870 ser_bound: ser_bound.get(),
871 de_bound: de_bound.get(),
872 borrowed_lifetimes: borrowed_lifetimes,
873 getter: getter.get(),
874 }
875 }
876
877 pub fn name(&self) -> &Name {
878 &self.name
879 }
880
881 pub fn rename_by_rule(&mut self, rule: &RenameRule) {
882 if !self.ser_renamed {
883 self.name.serialize = rule.apply_to_field(&self.name.serialize);
884 }
885 if !self.de_renamed {
886 self.name.deserialize = rule.apply_to_field(&self.name.deserialize);
887 }
888 }
889
890 pub fn skip_serializing(&self) -> bool {
891 self.skip_serializing
892 }
893
894 pub fn skip_deserializing(&self) -> bool {
895 self.skip_deserializing
896 }
897
898 pub fn skip_serializing_if(&self) -> Option<&syn::Path> {
899 self.skip_serializing_if.as_ref()
900 }
901
902 pub fn default(&self) -> &Default {
903 &self.default
904 }
905
906 pub fn serialize_with(&self) -> Option<&syn::Path> {
907 self.serialize_with.as_ref()
908 }
909
910 pub fn deserialize_with(&self) -> Option<&syn::Path> {
911 self.deserialize_with.as_ref()
912 }
913
914 pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
915 self.ser_bound.as_ref().map(|vec| &vec[..])
916 }
917
918 pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
919 self.de_bound.as_ref().map(|vec| &vec[..])
920 }
921
922 pub fn borrowed_lifetimes(&self) -> &BTreeSet<syn::Lifetime> {
923 &self.borrowed_lifetimes
924 }
925
926 pub fn getter(&self) -> Option<&syn::Path> {
927 self.getter.as_ref()
928 }
929 }
930
931 type SerAndDe<T> = (Option<T>, Option<T>);
932
933 fn get_ser_and_de<T, F>(
934 cx: &Ctxt,
935 attr_name: &'static str,
936 items: &[syn::NestedMetaItem],
937 f: F,
938 ) -> Result<SerAndDe<T>, ()>
939 where
940 F: Fn(&Ctxt, &str, &str, &syn::Lit) -> Result<T, ()>,
941 {
942 let mut ser_item = Attr::none(cx, attr_name);
943 let mut de_item = Attr::none(cx, attr_name);
944
945 for item in items {
946 match *item {
947 MetaItem(NameValue(ref name, ref lit)) if name == "serialize" => {
948 if let Ok(v) = f(cx, attr_name, name.as_ref(), lit) {
949 ser_item.set(v);
950 }
951 }
952
953 MetaItem(NameValue(ref name, ref lit)) if name == "deserialize" => {
954 if let Ok(v) = f(cx, attr_name, name.as_ref(), lit) {
955 de_item.set(v);
956 }
957 }
958
959 _ => {
960 cx.error(
961 format!(
962 "malformed {0} attribute, expected `{0}(serialize = ..., \
963 deserialize = ...)`",
964 attr_name
965 ),
966 );
967 return Err(());
968 }
969 }
970 }
971
972 Ok((ser_item.get(), de_item.get()))
973 }
974
975 fn get_renames(cx: &Ctxt, items: &[syn::NestedMetaItem]) -> Result<SerAndDe<String>, ()> {
976 get_ser_and_de(cx, "rename", items, get_string_from_lit)
977 }
978
979 fn get_where_predicates(
980 cx: &Ctxt,
981 items: &[syn::NestedMetaItem],
982 ) -> Result<SerAndDe<Vec<syn::WherePredicate>>, ()> {
983 get_ser_and_de(cx, "bound", items, parse_lit_into_where)
984 }
985
986 pub fn get_serde_meta_items(attr: &syn::Attribute) -> Option<Vec<syn::NestedMetaItem>> {
987 match attr.value {
988 List(ref name, ref items) if name == "serde" => Some(items.iter().cloned().collect()),
989 _ => None,
990 }
991 }
992
993 fn get_string_from_lit(
994 cx: &Ctxt,
995 attr_name: &str,
996 meta_item_name: &str,
997 lit: &syn::Lit,
998 ) -> Result<String, ()> {
999 if let syn::Lit::Str(ref s, _) = *lit {
1000 Ok(s.clone())
1001 } else {
1002 cx.error(
1003 format!(
1004 "expected serde {} attribute to be a string: `{} = \"...\"`",
1005 attr_name,
1006 meta_item_name
1007 ),
1008 );
1009 Err(())
1010 }
1011 }
1012
1013 fn parse_lit_into_path(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Path, ()> {
1014 let string = try!(get_string_from_lit(cx, attr_name, attr_name, lit));
1015 syn::parse_path(&string).map_err(|err| cx.error(err))
1016 }
1017
1018 fn parse_lit_into_where(
1019 cx: &Ctxt,
1020 attr_name: &str,
1021 meta_item_name: &str,
1022 lit: &syn::Lit,
1023 ) -> Result<Vec<syn::WherePredicate>, ()> {
1024 let string = try!(get_string_from_lit(cx, attr_name, meta_item_name, lit));
1025 if string.is_empty() {
1026 return Ok(Vec::new());
1027 }
1028
1029 let where_string = format!("where {}", string);
1030
1031 syn::parse_where_clause(&where_string)
1032 .map(|wh| wh.predicates)
1033 .map_err(|err| cx.error(err))
1034 }
1035
1036 fn parse_lit_into_ty(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Ty, ()> {
1037 let string = try!(get_string_from_lit(cx, attr_name, attr_name, lit));
1038
1039 syn::parse_type(&string).map_err(
1040 |_| {
1041 cx.error(format!("failed to parse type: {} = {:?}", attr_name, string),)
1042 },
1043 )
1044 }
1045
1046 // Parses a string literal like "'a + 'b + 'c" containing a nonempty list of
1047 // lifetimes separated by `+`.
1048 fn parse_lit_into_lifetimes(
1049 cx: &Ctxt,
1050 attr_name: &str,
1051 lit: &syn::Lit,
1052 ) -> Result<BTreeSet<syn::Lifetime>, ()> {
1053 let string = try!(get_string_from_lit(cx, attr_name, attr_name, lit));
1054 if string.is_empty() {
1055 cx.error("at least one lifetime must be borrowed");
1056 return Err(());
1057 }
1058
1059 named!(lifetimes -> Vec<syn::Lifetime>,
1060 separated_nonempty_list!(punct!("+"), syn::parse::lifetime)
1061 );
1062
1063 if let IResult::Done(rest, o) = lifetimes(&string) {
1064 if rest.trim().is_empty() {
1065 let mut set = BTreeSet::new();
1066 for lifetime in o {
1067 if !set.insert(lifetime.clone()) {
1068 cx.error(format!("duplicate borrowed lifetime `{}`", lifetime.ident));
1069 }
1070 }
1071 return Ok(set);
1072 }
1073 }
1074 Err(cx.error(format!("failed to parse borrowed lifetimes: {:?}", string)),)
1075 }
1076
1077 // Whether the type looks like it might be `std::borrow::Cow<T>` where elem="T".
1078 // This can have false negatives and false positives.
1079 //
1080 // False negative:
1081 //
1082 // use std::borrow::Cow as Pig;
1083 //
1084 // #[derive(Deserialize)]
1085 // struct S<'a> {
1086 // #[serde(borrow)]
1087 // pig: Pig<'a, str>,
1088 // }
1089 //
1090 // False positive:
1091 //
1092 // type str = [i16];
1093 //
1094 // #[derive(Deserialize)]
1095 // struct S<'a> {
1096 // #[serde(borrow)]
1097 // cow: Cow<'a, str>,
1098 // }
1099 fn is_cow(ty: &syn::Ty, elem: &str) -> bool {
1100 let path = match *ty {
1101 syn::Ty::Path(None, ref path) => path,
1102 _ => {
1103 return false;
1104 }
1105 };
1106 let seg = match path.segments.last() {
1107 Some(seg) => seg,
1108 None => {
1109 return false;
1110 }
1111 };
1112 let params = match seg.parameters {
1113 syn::PathParameters::AngleBracketed(ref params) => params,
1114 _ => {
1115 return false;
1116 }
1117 };
1118 seg.ident == "Cow" && params.lifetimes.len() == 1 &&
1119 params.types == vec![syn::parse_type(elem).unwrap()] && params.bindings.is_empty()
1120 }
1121
1122 // Whether the type looks like it might be `&T` where elem="T". This can have
1123 // false negatives and false positives.
1124 //
1125 // False negative:
1126 //
1127 // type Yarn = str;
1128 //
1129 // #[derive(Deserialize)]
1130 // struct S<'a> {
1131 // r: &'a Yarn,
1132 // }
1133 //
1134 // False positive:
1135 //
1136 // type str = [i16];
1137 //
1138 // #[derive(Deserialize)]
1139 // struct S<'a> {
1140 // r: &'a str,
1141 // }
1142 fn is_rptr(ty: &syn::Ty, elem: &str) -> bool {
1143 match *ty {
1144 syn::Ty::Rptr(Some(_), ref mut_ty) => {
1145 mut_ty.mutability == syn::Mutability::Immutable &&
1146 mut_ty.ty == syn::parse_type(elem).unwrap()
1147 }
1148 _ => false,
1149 }
1150 }
1151
1152 // All lifetimes that this type could borrow from a Deserializer.
1153 //
1154 // For example a type `S<'a, 'b>` could borrow `'a` and `'b`. On the other hand
1155 // a type `for<'a> fn(&'a str)` could not borrow `'a` from the Deserializer.
1156 //
1157 // This is used when there is an explicit or implicit `#[serde(borrow)]`
1158 // attribute on the field so there must be at least one borrowable lifetime.
1159 fn borrowable_lifetimes(
1160 cx: &Ctxt,
1161 name: &str,
1162 ty: &syn::Ty,
1163 ) -> Result<BTreeSet<syn::Lifetime>, ()> {
1164 let mut lifetimes = BTreeSet::new();
1165 collect_lifetimes(ty, &mut lifetimes);
1166 if lifetimes.is_empty() {
1167 Err(cx.error(format!("field `{}` has no lifetimes to borrow", name)),)
1168 } else {
1169 Ok(lifetimes)
1170 }
1171 }
1172
1173 fn collect_lifetimes(ty: &syn::Ty, out: &mut BTreeSet<syn::Lifetime>) {
1174 match *ty {
1175 syn::Ty::Slice(ref elem) |
1176 syn::Ty::Array(ref elem, _) |
1177 syn::Ty::Paren(ref elem) => {
1178 collect_lifetimes(elem, out);
1179 }
1180 syn::Ty::Ptr(ref elem) => {
1181 collect_lifetimes(&elem.ty, out);
1182 }
1183 syn::Ty::Rptr(ref lifetime, ref elem) => {
1184 out.extend(lifetime.iter().cloned());
1185 collect_lifetimes(&elem.ty, out);
1186 }
1187 syn::Ty::Tup(ref elems) => {
1188 for elem in elems {
1189 collect_lifetimes(elem, out);
1190 }
1191 }
1192 syn::Ty::Path(ref qself, ref path) => {
1193 if let Some(ref qself) = *qself {
1194 collect_lifetimes(&qself.ty, out);
1195 }
1196 for seg in &path.segments {
1197 if let syn::PathParameters::AngleBracketed(ref params) = seg.parameters {
1198 out.extend(params.lifetimes.iter().cloned());
1199 for ty in &params.types {
1200 collect_lifetimes(ty, out);
1201 }
1202 for binding in &params.bindings {
1203 collect_lifetimes(&binding.ty, out);
1204 }
1205 }
1206 }
1207 }
1208 syn::Ty::BareFn(_) |
1209 syn::Ty::Never |
1210 syn::Ty::TraitObject(_) |
1211 syn::Ty::ImplTrait(_) |
1212 syn::Ty::Infer |
1213 syn::Ty::Mac(_) => {}
1214 }
1215 }