Skip to content

Commit 12004e3

Browse files
committed
review feedback
1 parent 9b2d98c commit 12004e3

File tree

1 file changed

+39
-30
lines changed

1 file changed

+39
-30
lines changed

pyo3-macros-backend/src/pyclass.rs

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,7 @@ struct PyClassEnumVariantNamedField<'a> {
621621
}
622622

623623
/// `#[pyo3()]` options for pyclass enum variants
624+
#[derive(Default)]
624625
struct EnumVariantPyO3Options {
625626
name: Option<NameAttribute>,
626627
constructor: Option<ConstructorAttribute>,
@@ -646,31 +647,33 @@ impl Parse for EnumVariantPyO3Option {
646647

647648
impl EnumVariantPyO3Options {
648649
fn take_pyo3_options(attrs: &mut Vec<syn::Attribute>) -> Result<Self> {
649-
let mut options = EnumVariantPyO3Options {
650-
name: None,
651-
constructor: None,
652-
};
650+
let mut options = EnumVariantPyO3Options::default();
653651

654-
for option in take_pyo3_options(attrs)? {
655-
match option {
656-
EnumVariantPyO3Option::Name(name) => {
657-
ensure_spanned!(
658-
options.name.is_none(),
659-
name.span() => "`name` may only be specified once"
660-
);
661-
options.name = Some(name);
662-
}
663-
EnumVariantPyO3Option::Constructor(constructor) => {
652+
take_pyo3_options(attrs)?
653+
.into_iter()
654+
.try_for_each(|option| options.set_option(option))?;
655+
656+
Ok(options)
657+
}
658+
659+
fn set_option(&mut self, option: EnumVariantPyO3Option) -> syn::Result<()> {
660+
macro_rules! set_option {
661+
($key:ident) => {
662+
{
664663
ensure_spanned!(
665-
options.constructor.is_none(),
666-
constructor.span() => "`constructor` may only be specified once"
664+
self.$key.is_none(),
665+
$key.span() => concat!("`", stringify!($key), "` may only be specified once")
667666
);
668-
options.constructor = Some(constructor);
667+
self.$key = Some($key);
669668
}
670-
}
669+
};
671670
}
672671

673-
Ok(options)
672+
match option {
673+
EnumVariantPyO3Option::Constructor(constructor) => set_option!(constructor),
674+
EnumVariantPyO3Option::Name(name) => set_option!(name),
675+
}
676+
Ok(())
674677
}
675678
}
676679

@@ -704,18 +707,24 @@ fn impl_simple_enum(
704707
let variants = simple_enum.variants;
705708
let pytypeinfo = impl_pytypeinfo(cls, args, None, ctx);
706709

710+
for variant in &variants {
711+
ensure_spanned!(variant.options.constructor.is_none(), variant.options.constructor.span() => "`constructor` can't be used on a simple enum variant");
712+
}
713+
707714
let (default_repr, default_repr_slot) = {
708-
let variants_repr = variants.iter().map(|variant| {
709-
ensure_spanned!(variant.options.constructor.is_none(), variant.options.constructor.span() => "`constructor` can't be used on a simple enum variant");
710-
let variant_name = variant.ident;
711-
// Assuming all variants are unit variants because they are the only type we support.
712-
let repr = format!(
713-
"{}.{}",
714-
get_class_python_name(cls, args),
715-
variant.get_python_name(args),
716-
);
717-
Ok(quote! { #cls::#variant_name => #repr, })
718-
}).collect::<Result<TokenStream>>()?;
715+
let variants_repr = variants
716+
.iter()
717+
.map(|variant| {
718+
let variant_name = variant.ident;
719+
// Assuming all variants are unit variants because they are the only type we support.
720+
let repr = format!(
721+
"{}.{}",
722+
get_class_python_name(cls, args),
723+
variant.get_python_name(args),
724+
);
725+
Ok(quote! { #cls::#variant_name => #repr, })
726+
})
727+
.collect::<Result<TokenStream>>()?;
719728
let mut repr_impl: syn::ImplItemFn = syn::parse_quote! {
720729
fn __pyo3__repr__(&self) -> &'static str {
721730
match self {

0 commit comments

Comments
 (0)