]> git.proxmox.com Git - rustc.git/blobdiff - src/vendor/serde_derive_internals/src/attr.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / vendor / serde_derive_internals / src / attr.rs
index 454b8b59c0c58e8b215507406f72ecabd04e4e38..7baeb59bb31bcefa25602a97c5169dcdec8bda69 100644 (file)
@@ -512,6 +512,7 @@ pub struct Variant {
     other: bool,
     serialize_with: Option<syn::Path>,
     deserialize_with: Option<syn::Path>,
+    borrow: Option<syn::MetaItem>,
 }
 
 impl Variant {
@@ -524,6 +525,7 @@ impl Variant {
         let mut other = BoolAttr::none(cx, "other");
         let mut serialize_with = Attr::none(cx, "serialize_with");
         let mut deserialize_with = Attr::none(cx, "deserialize_with");
+        let mut borrow = Attr::none(cx, "borrow");
 
         for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) {
             for meta_item in meta_items {
@@ -599,6 +601,18 @@ impl Variant {
                         }
                     }
 
+                    // Defer `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b")]`
+                    MetaItem(ref mi) if mi.name() == "borrow" => {
+                        match variant.data {
+                            syn::VariantData::Tuple(ref fields) if fields.len() == 1 => {
+                                borrow.set(mi.clone());
+                            }
+                            _ => {
+                                cx.error("#[serde(borrow)] may only be used on newtype variants");
+                            }
+                        }
+                    }
+
                     MetaItem(ref meta_item) => {
                         cx.error(format!("unknown serde variant attribute `{}`", meta_item.name()));
                     }
@@ -627,6 +641,7 @@ impl Variant {
             other: other.get(),
             serialize_with: serialize_with.get(),
             deserialize_with: deserialize_with.get(),
+            borrow: borrow.get(),
         }
     }
 
@@ -699,7 +714,7 @@ pub enum Default {
 
 impl Field {
     /// Extract out the `#[serde(...)]` attributes from a struct field.
-    pub fn from_ast(cx: &Ctxt, index: usize, field: &syn::Field) -> Self {
+    pub fn from_ast(cx: &Ctxt, index: usize, field: &syn::Field, attrs: Option<&Variant>) -> Self {
         let mut ser_name = Attr::none(cx, "rename");
         let mut de_name = Attr::none(cx, "rename");
         let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
@@ -718,7 +733,13 @@ impl Field {
             None => index.to_string(),
         };
 
-        for meta_items in field.attrs.iter().filter_map(get_serde_meta_items) {
+        let variant_borrow = attrs
+            .map(|variant| &variant.borrow)
+            .unwrap_or(&None)
+            .as_ref()
+            .map(|borrow| vec![MetaItem(borrow.clone())]);
+
+        for meta_items in field.attrs.iter().filter_map(get_serde_meta_items).chain(variant_borrow) {
             for meta_item in meta_items {
                 match meta_item {
                     // Parse `#[serde(rename = "foo")]`