Use closure for generated properties in struct sequences.
@@ -346,37 +346,33 @@ pub fn impl_pyclass(attr: AttributeArgs, item: Item) -> Result<TokenStream2, Dia
}
pub fn impl_pystruct_sequence(attr: AttributeArgs, item: Item) -> Result<TokenStream2, Diagnostic> {
- if let Item::Struct(struc) = item {
+ let struc = if let Item::Struct(struc) = item {
+ struc
+ } else {
+ bail_span!(
+ item,
+ "#[pystruct_sequence] can only be on a struct declaration"
+ )
+ };
let class_def = generate_class_def(&struc.ident, "pystruct_sequence", attr, &struc.attrs)?;
- let mut methods = Vec::new();
- let mut method_references = Vec::new();
+ let mut properties = Vec::new();
let mut field_names = Vec::new();
for (i, field) in struc.fields.iter().enumerate() {
let idx = Index::from(i);
if let Some(ref field_name) = field.ident {
- let method_name = format!("get_{}", field_name);
- let method_ident = Ident::new(&method_name, field_name.span());
-
- let method = quote! {
- fn #method_ident(
- zelf: &::rustpython_vm::obj::objtuple::PyTuple,
- _vm: &::rustpython_vm::vm::VirtualMachine)
- -> ::rustpython_vm::pyobject::PyObjectRef {
- zelf.fast_getitem(#idx)
- }
- };
- methods.push(method);
let field_name_str = field_name.to_string();
// TODO add doc to the generated property
- let method_reference = quote! {
+ let property = quote! {
class.set_str_attr(
#field_name_str,
::rustpython_vm::obj::objproperty::PropertyBuilder::new(ctx)
- .add_getter(Self::#method_ident)
+ .add_getter(|zelf: &::rustpython_vm::obj::objtuple::PyTuple,
+ _vm: &::rustpython_vm::vm::VirtualMachine|
+ zelf.fast_getitem(#idx))
.create(),
);
};
- method_references.push(method_reference);
+ properties.push(property);
field_names.push(quote!(#field_name));
} else {
field_names.push(quote!(#idx));
@@ -398,15 +394,13 @@ pub fn impl_pystruct_sequence(attr: AttributeArgs, item: Item) -> Result<TokenSt
),*].into();
::rustpython_vm::pyobject::PyValue::into_ref_with_type(tuple, vm, cls)
}
-
- #(#methods)*
}
impl ::rustpython_vm::pyobject::PyClassImpl for #ty {
fn impl_extend_class(
ctx: &::rustpython_vm::pyobject::PyContext,
class: &::rustpython_vm::obj::objtype::PyClassRef,
) {
- #(#method_references)*
+ #(#properties)*
}
fn make_class(
@@ -419,10 +413,4 @@ pub fn impl_pystruct_sequence(attr: AttributeArgs, item: Item) -> Result<TokenSt
}
};
Ok(ret)
- } else {
- bail_span!(
- item,
- "#[pystruct_sequence] can only be on a struct declaration"
- )
- }
}
