diff --git a/derive/src/pyclass.rs b/derive/src/pyclass.rs index 3291a1418..8a1c84bc9 100644 --- a/derive/src/pyclass.rs +++ b/derive/src/pyclass.rs @@ -1,7 +1,7 @@ use super::Diagnostic; use crate::util::{ - path_eq, pyclass_ident_and_attrs, AttributeExt, ClassItemMeta, ContentItem, ContentItemInner, - ErrorVec, ItemMeta, ItemMetaInner, ItemNursery, ALL_ALLOWED_NAMES, + path_eq, pyclass_ident_and_attrs, ClassItemMeta, ContentItem, ContentItemInner, ErrorVec, + ItemMeta, ItemMetaInner, ItemNursery, ALL_ALLOWED_NAMES, }; use proc_macro2::TokenStream; use quote::{quote, quote_spanned, ToTokens}; @@ -268,11 +268,7 @@ where }?; let item_attr = args.attrs.remove(self.index()); - let item_meta = MethodItemMeta::from_nested( - ident.clone(), - item_attr.get_ident().unwrap().clone(), - item_attr.promoted_nested()?.into_iter(), - )?; + let item_meta = MethodItemMeta::from_attr(ident.clone(), &item_attr)?; let py_name = item_meta.method_name()?; let new_func = Ident::new(&format!("new_{}", &self.method_type), args.item.span()); @@ -304,11 +300,7 @@ where }?; let item_attr = args.attrs.remove(self.index()); - let item_meta = PropertyItemMeta::from_nested( - ident.clone(), - item_attr.get_ident().unwrap().clone(), - item_attr.promoted_nested()?.into_iter(), - )?; + let item_meta = PropertyItemMeta::from_attr(ident.clone(), &item_attr)?; let py_name = item_meta.property_name()?; let setter = item_meta.setter()?; @@ -331,11 +323,7 @@ where }?; let item_attr = args.attrs.remove(self.index()); - let item_meta = SlotItemMeta::from_nested( - ident.clone(), - item_attr.get_ident().unwrap().clone(), - item_attr.promoted_nested()?.into_iter(), - )?; + let item_meta = SlotItemMeta::from_attr(ident.clone(), &item_attr)?; let slot_ident = item_meta.slot_name()?; let slot_name = slot_ident.to_string(); diff --git a/derive/src/pymodule.rs b/derive/src/pymodule.rs index 4361b065d..ca75aa9f2 100644 --- a/derive/src/pymodule.rs +++ b/derive/src/pymodule.rs @@ -253,11 +253,7 @@ impl ModuleItem for FunctionItem { }; let item_attr = args.attrs.remove(self.index()); - let item_meta = SimpleItemMeta::from_nested( - ident.clone(), - item_attr.get_ident().unwrap().clone(), - item_attr.promoted_nested()?.into_iter(), - )?; + let item_meta = SimpleItemMeta::from_attr(ident.clone(), &item_attr)?; let py_name = item_meta.simple_name()?; let item = { @@ -283,7 +279,7 @@ impl ModuleItem for ClassItem { let (module_name, class_name) = { let class_attr = &mut args.attrs[self.inner.index]; if self.pyattrs.is_empty() { - // check noattr before ClassItemMeta::from_nested + // check noattr before ClassItemMeta::from_attr let noattr = class_attr.try_remove_name("noattr")?; if noattr.is_none() { return Err(syn::Error::new_spanned( @@ -297,11 +293,7 @@ impl ModuleItem for ClassItem { } } - let class_meta = ClassItemMeta::from_nested( - ident.clone(), - class_attr.get_ident().unwrap().clone(), - class_attr.promoted_nested()?.into_iter(), - )?; + let class_meta = ClassItemMeta::from_attr(ident.clone(), class_attr)?; let module_name = args.context.name.clone(); class_attr.fill_nested_meta("module", || { parse_quote! {module = #module_name} @@ -312,12 +304,7 @@ impl ModuleItem for ClassItem { for attr_index in self.pyattrs.iter().rev() { let mut loop_unit = || { let attr_attr = args.attrs.remove(*attr_index); - let (meta_ident, nested) = attr_attr.ident_and_promoted_nested()?; - let item_meta = SimpleItemMeta::from_nested( - ident.clone(), - meta_ident.clone(), - nested.into_iter(), - )?; + let item_meta = SimpleItemMeta::from_attr(ident.clone(), &attr_attr)?; let py_name = item_meta .optional_name() @@ -345,17 +332,17 @@ impl ModuleItem for ClassItem { impl ModuleItem for AttributeItem { fn gen_module_item(&self, args: ModuleItemArgs<'_>) -> Result<()> { - let get_py_name = |attrs: &mut Vec, ident: &Ident| -> Result<_> { - let (meta_ident, nested) = attrs[self.inner.index].ident_and_promoted_nested()?; - let item_meta = - SimpleItemMeta::from_nested(ident.clone(), meta_ident.clone(), nested.into_iter())?; + let cfgs = args.cfgs.to_vec(); + let attr = args.attrs.remove(self.index()); + let get_py_name = |attr: &Attribute, ident: &Ident| -> Result<_> { + let item_meta = SimpleItemMeta::from_attr(ident.clone(), attr)?; let py_name = item_meta.simple_name()?; Ok(py_name) }; let (py_name, tokens) = match args.item { Item::Fn(syn::ItemFn { sig, .. }) => { let ident = &sig.ident; - let py_name = get_py_name(args.attrs, &ident)?; + let py_name = get_py_name(&attr, &ident)?; ( py_name.clone(), quote! { @@ -364,7 +351,7 @@ impl ModuleItem for AttributeItem { ) } Item::Const(syn::ItemConst { ident, .. }) => { - let py_name = get_py_name(args.attrs, &ident)?; + let py_name = get_py_name(&attr, &ident)?; ( py_name.clone(), quote! { @@ -384,7 +371,7 @@ impl ModuleItem for AttributeItem { } }; - let py_name = get_py_name(args.attrs, &ident)?; + let py_name = get_py_name(&attr, &ident)?; ( py_name.clone(), quote! { @@ -398,11 +385,10 @@ impl ModuleItem for AttributeItem { ) } }; - args.attrs.remove(self.index()); args.context .module_extend_items - .add_item(py_name, args.cfgs.to_vec(), tokens)?; + .add_item(py_name, cfgs, tokens)?; Ok(()) } diff --git a/derive/src/util.rs b/derive/src/util.rs index cf262b977..cbd7ec5ae 100644 --- a/derive/src/util.rs +++ b/derive/src/util.rs @@ -177,6 +177,11 @@ impl ItemMetaInner { pub(crate) trait ItemMeta: Sized { const ALLOWED_NAMES: &'static [&'static str]; + fn from_attr(item_ident: Ident, attr: &Attribute) -> Result { + let (meta_ident, nested) = attr.ident_and_promoted_nested()?; + Self::from_nested(item_ident, meta_ident.clone(), nested.into_iter()) + } + fn from_nested(item_ident: Ident, meta_ident: Ident, nested: I) -> Result where I: std::iter::Iterator,