Allow borrow attribute on newtype variants

This commit is contained in:
David Tolnay
2017-11-05 11:21:39 -08:00
parent ab68132b1f
commit 40db31691a
5 changed files with 81 additions and 11 deletions
+23 -2
View 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")]`