other: bool,
serialize_with: Option<syn::Path>,
deserialize_with: Option<syn::Path>,
+ borrow: Option<syn::MetaItem>,
}
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 {
}
}
+ // 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()));
}
other: other.get(),
serialize_with: serialize_with.get(),
deserialize_with: deserialize_with.get(),
+ borrow: borrow.get(),
}
}
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");
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")]`