1 // Copyright 2017 Serde Developers
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.
11 use syn
::MetaItem
::{List, NameValue, Word}
;
12 use syn
::NestedMetaItem
::{Literal, MetaItem}
;
14 use std
::collections
::BTreeSet
;
15 use std
::str::FromStr
;
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.
25 pub use case
::RenameRule
;
33 impl<'c
, T
> Attr
<'c
, T
> {
34 fn none(cx
: &'c Ctxt
, name
: &'
static str) -> Self {
42 fn set(&mut self, value
: T
) {
43 if self.value
.is_some() {
45 .error(format
!("duplicate serde attribute `{}`", self.name
));
47 self.value
= Some(value
);
51 fn set_opt(&mut self, value
: Option
<T
>) {
52 if let Some(value
) = value
{
57 fn set_if_none(&mut self, value
: T
) {
58 if self.value
.is_none() {
59 self.value
= Some(value
);
63 fn get(self) -> Option
<T
> {
68 struct BoolAttr
<'c
>(Attr
<'c
, ()>);
70 impl<'c
> BoolAttr
<'c
> {
71 fn none(cx
: &'c Ctxt
, name
: &'
static str) -> Self {
72 BoolAttr(Attr
::none(cx
, name
))
75 fn set_true(&mut self) {
79 fn get(&self) -> bool
{
80 self.0.value
.is_some()
91 /// Return the container name for the container when serializing.
92 pub fn serialize_name(&self) -> String
{
93 self.serialize
.clone()
96 /// Return the container name for the container when deserializing.
97 pub fn deserialize_name(&self) -> String
{
98 self.deserialize
.clone()
102 /// Represents container (e.g. struct) attribute information
104 pub struct Container
{
106 deny_unknown_fields
: bool
,
108 rename_all
: RenameRule
,
109 ser_bound
: Option
<Vec
<syn
::WherePredicate
>>,
110 de_bound
: Option
<Vec
<syn
::WherePredicate
>>,
112 from_type
: Option
<syn
::Ty
>,
113 into_type
: Option
<syn
::Ty
>,
114 remote
: Option
<syn
::Path
>,
115 identifier
: Identifier
,
118 /// Styles of representing an enum.
124 /// {"variant1": {"key1": "value1", "key2": "value2"}}
128 /// `#[serde(tag = "type")]`
131 /// {"type": "variant1", "key1": "value1", "key2": "value2"}
133 Internal { tag: String }
,
135 /// `#[serde(tag = "t", content = "c")]`
138 /// {"t": "variant1", "c": {"key1": "value1", "key2": "value2"}}
140 Adjacent { tag: String, content: String }
,
142 /// `#[serde(untagged)]`
145 /// {"key1": "value1", "key2": "value2"}
150 /// Whether this enum represents the fields of a struct or the variants of an
152 #[derive(Copy, Clone, Debug)]
153 pub enum Identifier
{
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.
162 /// This enum represents the variants of an enum. All of the variants must
163 /// be unit variants.
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");
186 for meta_items
in item
.attrs
.iter().filter_map(get_serde_meta_items
) {
187 for meta_item
in meta_items
{
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());
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
);
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
),
211 cx
.error(format
!("unknown rename rule for #[serde(rename_all \
219 // Parse `#[serde(deny_unknown_fields)]`
220 MetaItem(Word(ref name
)) if name
== "deny_unknown_fields" => {
221 deny_unknown_fields
.set_true();
224 // Parse `#[serde(default)]`
225 MetaItem(Word(ref name
)) if name
== "default" => {
227 syn
::Body
::Struct(syn
::VariantData
::Struct(_
)) => {
228 default.set(Default
::Default
);
232 "#[serde(default)] can only be used on structs \
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
) {
243 syn
::Body
::Struct(syn
::VariantData
::Struct(_
)) => {
244 default.set(Default
::Path(path
));
248 "#[serde(default = \"...\")] can only be used \
249 on structs with named fields",
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
);
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
);
273 // Parse `#[serde(untagged)]`
274 MetaItem(Word(ref name
)) if name
== "untagged" => {
276 syn
::Body
::Enum(_
) => {
279 syn
::Body
::Struct(_
) => {
280 cx
.error("#[serde(untagged)] can only be used on enums")
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
) {
289 syn
::Body
::Enum(_
) => {
292 syn
::Body
::Struct(_
) => {
293 cx
.error("#[serde(tag = \"...\")] can only be used on enums")
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
) {
303 syn
::Body
::Enum(_
) => {
306 syn
::Body
::Struct(_
) => {
308 "#[serde(content = \"...\")] can only be used on \
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
));
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
));
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
) {
337 // Parse `#[serde(field_identifier)]`
338 MetaItem(Word(ref name
)) if name
== "field_identifier" => {
339 field_identifier
.set_true();
342 // Parse `#[serde(variant_identifier)]`
343 MetaItem(Word(ref name
)) if name
== "variant_identifier" => {
344 variant_identifier
.set_true();
347 MetaItem(ref meta_item
) => {
348 cx
.error(format
!("unknown serde container attribute `{}`",
353 cx
.error("unexpected literal in serde container attribute");
361 serialize
: ser_name
.get().unwrap_or_else(|| item
.ident
.to_string()),
362 deserialize
: de_name
.get().unwrap_or_else(|| item
.ident
.to_string()),
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
),
377 pub fn name(&self) -> &Name
{
381 pub fn rename_all(&self) -> &RenameRule
{
385 pub fn deny_unknown_fields(&self) -> bool
{
386 self.deny_unknown_fields
389 pub fn default(&self) -> &Default
{
393 pub fn ser_bound(&self) -> Option
<&[syn
::WherePredicate
]> {
394 self.ser_bound
.as_ref().map(|vec
| &vec
[..])
397 pub fn de_bound(&self) -> Option
<&[syn
::WherePredicate
]> {
398 self.de_bound
.as_ref().map(|vec
| &vec
[..])
401 pub fn tag(&self) -> &EnumTag
{
405 pub fn from_type(&self) -> Option
<&syn
::Ty
> {
406 self.from_type
.as_ref()
409 pub fn into_type(&self) -> Option
<&syn
::Ty
> {
410 self.into_type
.as_ref()
413 pub fn remote(&self) -> Option
<&syn
::Path
> {
417 pub fn identifier(&self) -> Identifier
{
424 item
: &syn
::DeriveInput
,
426 internal_tag
: Attr
<String
>,
427 content
: Attr
<String
>,
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
{
437 syn
::VariantData
::Struct(_
) |
438 syn
::VariantData
::Unit
=> {}
439 syn
::VariantData
::Tuple(ref fields
) => {
440 if fields
.len() != 1 {
442 "#[serde(tag = \"...\")] cannot be used with tuple \
451 EnumTag
::Internal { tag: tag }
453 (true, Some(_
), None
) => {
454 cx
.error("enum cannot be both untagged and internally tagged");
455 EnumTag
::External
// doesn't matter, will error
457 (false, None
, Some(_
)) => {
458 cx
.error("#[serde(tag = \"...\", content = \"...\")] must be used together",);
461 (true, None
, Some(_
)) => {
462 cx
.error("untagged enum cannot have #[serde(content = \"...\")]");
465 (false, Some(tag
), Some(content
)) => {
471 (true, Some(_
), Some(_
)) => {
472 cx
.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]",);
478 fn decide_identifier(
480 item
: &syn
::DeriveInput
,
481 field_identifier
: BoolAttr
,
482 variant_identifier
: BoolAttr
,
484 match (&item
.body
, field_identifier
.get(), variant_identifier
.get()) {
485 (_
, false, false) => Identifier
::No
,
487 cx
.error("`field_identifier` and `variant_identifier` cannot both be set",);
490 (&syn
::Body
::Struct(_
), true, false) => {
491 cx
.error("`field_identifier` can only be used on an enum");
494 (&syn
::Body
::Struct(_
), false, true) => {
495 cx
.error("`variant_identifier` can only be used on an enum");
498 (&syn
::Body
::Enum(_
), true, false) => Identifier
::Field
,
499 (&syn
::Body
::Enum(_
), false, true) => Identifier
::Variant
,
503 /// Represents variant attribute information
509 rename_all
: RenameRule
,
510 skip_deserializing
: bool
,
511 skip_serializing
: bool
,
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");
524 for meta_items
in variant
.attrs
.iter().filter_map(get_serde_meta_items
) {
525 for meta_item
in meta_items
{
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());
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
);
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
),
549 cx
.error(format
!("unknown rename rule for #[serde(rename_all \
557 // Parse `#[serde(skip_deserializing)]`
558 MetaItem(Word(ref name
)) if name
== "skip_deserializing" => {
559 skip_deserializing
.set_true();
562 // Parse `#[serde(skip_serializing)]`
563 MetaItem(Word(ref name
)) if name
== "skip_serializing" => {
564 skip_serializing
.set_true();
567 // Parse `#[serde(other)]`
568 MetaItem(Word(ref name
)) if name
== "other" => {
572 MetaItem(ref meta_item
) => {
573 cx
.error(format
!("unknown serde variant attribute `{}`", meta_item
.name()));
577 cx
.error("unexpected literal in serde variant attribute");
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();
589 serialize
: ser_name
.unwrap_or_else(|| variant
.ident
.to_string()),
590 deserialize
: de_name
.unwrap_or_else(|| variant
.ident
.to_string()),
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(),
601 pub fn name(&self) -> &Name
{
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
);
609 if !self.de_renamed
{
610 self.name
.deserialize
= rule
.apply_to_variant(&self.name
.deserialize
);
614 pub fn rename_all(&self) -> &RenameRule
{
618 pub fn skip_deserializing(&self) -> bool
{
619 self.skip_deserializing
622 pub fn skip_serializing(&self) -> bool
{
623 self.skip_serializing
626 pub fn other(&self) -> bool
{
631 /// Represents field attribute information
637 skip_serializing
: bool
,
638 skip_deserializing
: bool
,
639 skip_serializing_if
: Option
<syn
::Path
>,
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
>,
649 /// Represents the default to use for a field when deserializing.
650 #[derive(Debug, PartialEq)]
652 /// Field must always be specified because it does not have a default.
654 /// The default is given by `std::default::Default::default()`.
656 /// The default is given by this function.
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");
676 let ident
= match field
.ident
{
677 Some(ref ident
) => ident
.to_string(),
678 None
=> index
.to_string(),
681 for meta_items
in field
.attrs
.iter().filter_map(get_serde_meta_items
) {
682 for meta_item
in meta_items
{
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());
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
);
700 // Parse `#[serde(default)]`
701 MetaItem(Word(ref name
)) if name
== "default" => {
702 default.set(Default
::Default
);
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
));
712 // Parse `#[serde(skip_serializing)]`
713 MetaItem(Word(ref name
)) if name
== "skip_serializing" => {
714 skip_serializing
.set_true();
717 // Parse `#[serde(skip_deserializing)]`
718 MetaItem(Word(ref name
)) if name
== "skip_deserializing" => {
719 skip_deserializing
.set_true();
722 // Parse `#[serde(skip)]`
723 MetaItem(Word(ref name
)) if name
== "skip" => {
724 skip_serializing
.set_true();
725 skip_deserializing
.set_true();
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
) {
793 "field `{}` does not have lifetime {}",
800 borrowed_lifetimes
.set(lifetimes
);
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
) {
812 MetaItem(ref meta_item
) => {
813 cx
.error(format
!("unknown serde field attribute `{}`", meta_item
.name()),);
817 cx
.error("unexpected literal in serde field attribute");
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
);
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:
833 // impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
835 // A #[serde(borrow)] attribute enables borrowing that corresponds
836 // roughly to these impls:
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
);
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();
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();
859 serialize
: ser_name
.unwrap_or_else(|| ident
.clone()),
860 deserialize
: de_name
.unwrap_or(ident
),
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(),
877 pub fn name(&self) -> &Name
{
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
);
885 if !self.de_renamed
{
886 self.name
.deserialize
= rule
.apply_to_field(&self.name
.deserialize
);
890 pub fn skip_serializing(&self) -> bool
{
891 self.skip_serializing
894 pub fn skip_deserializing(&self) -> bool
{
895 self.skip_deserializing
898 pub fn skip_serializing_if(&self) -> Option
<&syn
::Path
> {
899 self.skip_serializing_if
.as_ref()
902 pub fn default(&self) -> &Default
{
906 pub fn serialize_with(&self) -> Option
<&syn
::Path
> {
907 self.serialize_with
.as_ref()
910 pub fn deserialize_with(&self) -> Option
<&syn
::Path
> {
911 self.deserialize_with
.as_ref()
914 pub fn ser_bound(&self) -> Option
<&[syn
::WherePredicate
]> {
915 self.ser_bound
.as_ref().map(|vec
| &vec
[..])
918 pub fn de_bound(&self) -> Option
<&[syn
::WherePredicate
]> {
919 self.de_bound
.as_ref().map(|vec
| &vec
[..])
922 pub fn borrowed_lifetimes(&self) -> &BTreeSet
<syn
::Lifetime
> {
923 &self.borrowed_lifetimes
926 pub fn getter(&self) -> Option
<&syn
::Path
> {
931 type SerAndDe
<T
> = (Option
<T
>, Option
<T
>);
933 fn get_ser_and_de
<T
, F
>(
935 attr_name
: &'
static str,
936 items
: &[syn
::NestedMetaItem
],
938 ) -> Result
<SerAndDe
<T
>, ()>
940 F
: Fn(&Ctxt
, &str, &str, &syn
::Lit
) -> Result
<T
, ()>,
942 let mut ser_item
= Attr
::none(cx
, attr_name
);
943 let mut de_item
= Attr
::none(cx
, attr_name
);
947 MetaItem(NameValue(ref name
, ref lit
)) if name
== "serialize" => {
948 if let Ok(v
) = f(cx
, attr_name
, name
.as_ref(), lit
) {
953 MetaItem(NameValue(ref name
, ref lit
)) if name
== "deserialize" => {
954 if let Ok(v
) = f(cx
, attr_name
, name
.as_ref(), lit
) {
962 "malformed {0} attribute, expected `{0}(serialize = ..., \
963 deserialize = ...)`",
972 Ok((ser_item
.get(), de_item
.get()))
975 fn get_renames(cx
: &Ctxt
, items
: &[syn
::NestedMetaItem
]) -> Result
<SerAndDe
<String
>, ()> {
976 get_ser_and_de(cx
, "rename", items
, get_string_from_lit
)
979 fn get_where_predicates(
981 items
: &[syn
::NestedMetaItem
],
982 ) -> Result
<SerAndDe
<Vec
<syn
::WherePredicate
>>, ()> {
983 get_ser_and_de(cx
, "bound", items
, parse_lit_into_where
)
986 pub fn get_serde_meta_items(attr
: &syn
::Attribute
) -> Option
<Vec
<syn
::NestedMetaItem
>> {
988 List(ref name
, ref items
) if name
== "serde" => Some(items
.iter().cloned().collect()),
993 fn get_string_from_lit(
996 meta_item_name
: &str,
998 ) -> Result
<String
, ()> {
999 if let syn
::Lit
::Str(ref s
, _
) = *lit
{
1004 "expected serde {} attribute to be a string: `{} = \"...\"`",
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
))
1018 fn parse_lit_into_where(
1021 meta_item_name
: &str,
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());
1029 let where_string
= format
!("where {}", string
);
1031 syn
::parse_where_clause(&where_string
)
1032 .map(|wh
| wh
.predicates
)
1033 .map_err(|err
| cx
.error(err
))
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
));
1039 syn
::parse_type(&string
).map_err(
1041 cx
.error(format
!("failed to parse type: {} = {:?}", attr_name
, string
),)
1046 // Parses a string literal like "'a + 'b + 'c" containing a nonempty list of
1047 // lifetimes separated by `+`.
1048 fn parse_lit_into_lifetimes(
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");
1059 named
!(lifetimes
-> Vec
<syn
::Lifetime
>,
1060 separated_nonempty_list
!(punct
!("+"), syn
::parse
::lifetime
)
1063 if let IResult
::Done(rest
, o
) = lifetimes(&string
) {
1064 if rest
.trim().is_empty() {
1065 let mut set
= BTreeSet
::new();
1067 if !set
.insert(lifetime
.clone()) {
1068 cx
.error(format
!("duplicate borrowed lifetime `{}`", lifetime
.ident
));
1074 Err(cx
.error(format
!("failed to parse borrowed lifetimes: {:?}", string
)),)
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.
1082 // use std::borrow::Cow as Pig;
1084 // #[derive(Deserialize)]
1087 // pig: Pig<'a, str>,
1092 // type str = [i16];
1094 // #[derive(Deserialize)]
1097 // cow: Cow<'a, str>,
1099 fn is_cow(ty
: &syn
::Ty
, elem
: &str) -> bool
{
1100 let path
= match *ty
{
1101 syn
::Ty
::Path(None
, ref path
) => path
,
1106 let seg
= match path
.segments
.last() {
1112 let params
= match seg
.parameters
{
1113 syn
::PathParameters
::AngleBracketed(ref params
) => params
,
1118 seg
.ident
== "Cow" && params
.lifetimes
.len() == 1 &&
1119 params
.types
== vec
![syn
::parse_type(elem
).unwrap()] && params
.bindings
.is_empty()
1122 // Whether the type looks like it might be `&T` where elem="T". This can have
1123 // false negatives and false positives.
1129 // #[derive(Deserialize)]
1136 // type str = [i16];
1138 // #[derive(Deserialize)]
1142 fn is_rptr(ty
: &syn
::Ty
, elem
: &str) -> bool
{
1144 syn
::Ty
::Rptr(Some(_
), ref mut_ty
) => {
1145 mut_ty
.mutability
== syn
::Mutability
::Immutable
&&
1146 mut_ty
.ty
== syn
::parse_type(elem
).unwrap()
1152 // All lifetimes that this type could borrow from a Deserializer.
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.
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(
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
)),)
1173 fn collect_lifetimes(ty
: &syn
::Ty
, out
: &mut BTreeSet
<syn
::Lifetime
>) {
1175 syn
::Ty
::Slice(ref elem
) |
1176 syn
::Ty
::Array(ref elem
, _
) |
1177 syn
::Ty
::Paren(ref elem
) => {
1178 collect_lifetimes(elem
, out
);
1180 syn
::Ty
::Ptr(ref elem
) => {
1181 collect_lifetimes(&elem
.ty
, out
);
1183 syn
::Ty
::Rptr(ref lifetime
, ref elem
) => {
1184 out
.extend(lifetime
.iter().cloned());
1185 collect_lifetimes(&elem
.ty
, out
);
1187 syn
::Ty
::Tup(ref elems
) => {
1189 collect_lifetimes(elem
, out
);
1192 syn
::Ty
::Path(ref qself
, ref path
) => {
1193 if let Some(ref qself
) = *qself
{
1194 collect_lifetimes(&qself
.ty
, out
);
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 ¶ms
.types
{
1200 collect_lifetimes(ty
, out
);
1202 for binding
in ¶ms
.bindings
{
1203 collect_lifetimes(&binding
.ty
, out
);
1208 syn
::Ty
::BareFn(_
) |
1210 syn
::Ty
::TraitObject(_
) |
1211 syn
::Ty
::ImplTrait(_
) |
1213 syn
::Ty
::Mac(_
) => {}