From 5edaf12d2a9e2c20f15b2bf22c20ca4fc03dc445 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sun, 23 Aug 2020 18:37:25 +0900 Subject: [PATCH] pyclass_ident_and_attrs --- derive/src/pyclass.rs | 14 +++----------- derive/src/pymodule.rs | 12 +++--------- derive/src/util.rs | 12 ++++++++++++ 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/derive/src/pyclass.rs b/derive/src/pyclass.rs index 96c055e54d..aa77b4e632 100644 --- a/derive/src/pyclass.rs +++ b/derive/src/pyclass.rs @@ -1,7 +1,7 @@ use super::Diagnostic; use crate::util::{ - path_eq, AttributeExt, ClassItemMeta, ContentItem, ContentItemInner, ErrorVec, ItemMeta, - ItemMetaInner, ItemNursery, ALL_ALLOWED_NAMES, + path_eq, pyclass_ident_and_attrs, AttributeExt, ClassItemMeta, ContentItem, ContentItemInner, + ErrorVec, ItemMeta, ItemMetaInner, ItemNursery, ALL_ALLOWED_NAMES, }; use proc_macro2::TokenStream; use quote::{quote, quote_spanned, ToTokens}; @@ -165,15 +165,7 @@ pub(crate) fn impl_pyclass( attr: AttributeArgs, item: Item, ) -> std::result::Result { - let (ident, attrs) = match &item { - Item::Struct(syn::ItemStruct { ident, attrs, .. }) => (ident, attrs), - Item::Enum(syn::ItemEnum { ident, attrs, .. }) => (ident, attrs), - other => bail_span!( - other, - "#[pyclass] can only be on a struct or enum declaration" - ), - }; - + let (ident, attrs) = pyclass_ident_and_attrs(&item)?; let fake_ident = Ident::new("pyclass", item.span()); let class_meta = ClassItemMeta::from_nested(ident.clone(), fake_ident, attr.into_iter())?; let class_name = class_meta.class_name()?; diff --git a/derive/src/pymodule.rs b/derive/src/pymodule.rs index d85ae35536..152236fd33 100644 --- a/derive/src/pymodule.rs +++ b/derive/src/pymodule.rs @@ -1,7 +1,7 @@ use crate::error::Diagnostic; use crate::util::{ - AttributeExt, ClassItemMeta, ContentItem, ContentItemInner, ErrorVec, ItemMeta, ItemNursery, - SimpleItemMeta, ALL_ALLOWED_NAMES, + pyclass_ident_and_attrs, AttributeExt, ClassItemMeta, ContentItem, ContentItemInner, ErrorVec, + ItemMeta, ItemNursery, SimpleItemMeta, ALL_ALLOWED_NAMES, }; use proc_macro2::TokenStream; use quote::{quote, quote_spanned, ToTokens}; @@ -279,13 +279,7 @@ impl ModuleItem for FunctionItem { impl ModuleItem for ClassItem { fn gen_module_item(&self, args: ModuleItemArgs<'_>) -> Result<()> { - let ident = match args.item { - Item::Struct(syn::ItemStruct { ident, .. }) => ident.clone(), - Item::Enum(syn::ItemEnum { ident, .. }) => ident.clone(), - other => { - return Err(self.new_syn_error(other.span(), "can only be on a struct or enum")) - } - }; + let (ident, _) = pyclass_ident_and_attrs(&args.item)?; let (module_name, class_name) = { let class_attr = &mut args.attrs[self.inner.index]; if self.pyattrs.is_empty() { diff --git a/derive/src/util.rs b/derive/src/util.rs index 2fa3e40efd..0759ce91ac 100644 --- a/derive/src/util.rs +++ b/derive/src/util.rs @@ -397,6 +397,18 @@ impl AttributeExt for Attribute { } } +pub(crate) fn pyclass_ident_and_attrs(item: &syn::Item) -> Result<(&Ident, &[Attribute])> { + use syn::Item::*; + match item { + Struct(syn::ItemStruct { ident, attrs, .. }) => Ok((ident, attrs)), + Enum(syn::ItemEnum { ident, attrs, .. }) => Ok((ident, attrs)), + other => Err(syn::Error::new_spanned( + other, + "#[pyclass] can only be on a struct or enum declaration", + )), + } +} + pub(crate) trait ErrorVec: Sized { fn into_error(self) -> Option; fn into_result(self) -> Result<()> {