From 5bc5da8da18e87aa4a03d53442834ec45be6080b Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Sun, 30 Aug 2020 14:53:06 -0500 Subject: [PATCH] Move the PyStructSequence impl to a separate mod --- derive/src/lib.rs | 3 +- derive/src/pyclass.rs | 62 +------------------------------------- derive/src/pystructseq.rs | 63 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 62 deletions(-) create mode 100644 derive/src/pystructseq.rs diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 613bbc8fa..2be5629fb 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -13,6 +13,7 @@ mod compile_bytecode; mod from_args; mod pyclass; mod pymodule; +mod pystructseq; mod util; use error::{extract_spans, Diagnostic}; @@ -55,7 +56,7 @@ pub fn pymodule(attr: TokenStream, item: TokenStream) -> TokenStream { #[proc_macro_derive(PyStructSequence)] pub fn pystruct_sequence(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); - result_to_tokens(pyclass::impl_pystruct_sequence(input)) + result_to_tokens(pystructseq::impl_pystruct_sequence(input)) } #[proc_macro] diff --git a/derive/src/pyclass.rs b/derive/src/pyclass.rs index 9b0be8574..66a7de48d 100644 --- a/derive/src/pyclass.rs +++ b/derive/src/pyclass.rs @@ -7,8 +7,7 @@ use proc_macro2::TokenStream; use quote::{quote, quote_spanned, ToTokens}; use std::collections::HashMap; use syn::{ - parse_quote, spanned::Spanned, Attribute, AttributeArgs, DeriveInput, Ident, Index, Item, Meta, - NestedMeta, Result, + parse_quote, spanned::Spanned, Attribute, AttributeArgs, Ident, Item, Meta, NestedMeta, Result, }; use syn_ext::ext::*; @@ -216,65 +215,6 @@ pub(crate) fn impl_pyclass( Ok(ret) } -pub(crate) fn impl_pystruct_sequence( - input: DeriveInput, -) -> std::result::Result { - let fields = if let syn::Data::Struct(ref struc) = input.data { - &struc.fields - } else { - bail_span!( - input, - "#[pystruct_sequence] can only be on a struct declaration" - ) - }; - - let mut properties = Vec::new(); - let mut field_names = Vec::new(); - match fields { - syn::Fields::Named(fields) => { - for (i, field) in fields.named.iter().enumerate() { - let idx = Index::from(i); - let field_name = field.ident.as_ref().unwrap(); - let field_name_str = field_name.to_string(); - // TODO add doc to the generated property - let property = quote! { - class.set_str_attr( - #field_name_str, - ctx.new_readonly_getset( - #field_name_str, - |zelf: &::rustpython_vm::obj::objtuple::PyTuple, - _vm: &::rustpython_vm::VirtualMachine| { - zelf.fast_getitem(#idx) - } - ), - ); - }; - properties.push(property); - field_names.push(quote!(#field_name)); - } - } - _ => bail_span!( - input, - "#[pystruct_sequence] can only be on a struct with named fields" - ), - } - - let ty = &input.ident; - let ret = quote! { - impl ::rustpython_vm::pyobject::PyStructSequence for #ty { - const FIELD_NAMES: &'static [&'static str] = &[#(stringify!(#field_names)),*]; - fn to_tuple(&self, vm: &::rustpython_vm::VirtualMachine,) -> ::rustpython_vm::obj::objtuple::PyTuple { - let items = vec![#(::rustpython_vm::pyobject::IntoPyObject::into_pyobject( - ::std::clone::Clone::clone(&self.#field_names), - vm, - )),*]; - items.into() - } - } - }; - Ok(ret) -} - /// #[pymethod] and #[pyclassmethod] struct MethodItem { inner: ContentItemInner, diff --git a/derive/src/pystructseq.rs b/derive/src/pystructseq.rs new file mode 100644 index 000000000..d5286ffd9 --- /dev/null +++ b/derive/src/pystructseq.rs @@ -0,0 +1,63 @@ +use super::Diagnostic; +use proc_macro2::TokenStream; +use quote::quote; +use syn::{DeriveInput, Index}; + +pub(crate) fn impl_pystruct_sequence( + input: DeriveInput, +) -> std::result::Result { + let fields = if let syn::Data::Struct(ref struc) = input.data { + &struc.fields + } else { + bail_span!( + input, + "#[pystruct_sequence] can only be on a struct declaration" + ) + }; + + let mut properties = Vec::new(); + let mut field_names = Vec::new(); + match fields { + syn::Fields::Named(fields) => { + for (i, field) in fields.named.iter().enumerate() { + let idx = Index::from(i); + let field_name = field.ident.as_ref().unwrap(); + let field_name_str = field_name.to_string(); + // TODO add doc to the generated property + let property = quote! { + class.set_str_attr( + #field_name_str, + ctx.new_readonly_getset( + #field_name_str, + |zelf: &::rustpython_vm::obj::objtuple::PyTuple, + _vm: &::rustpython_vm::VirtualMachine| { + zelf.fast_getitem(#idx) + } + ), + ); + }; + properties.push(property); + field_names.push(quote!(#field_name)); + } + } + _ => bail_span!( + input, + "#[pystruct_sequence] can only be on a struct with named fields" + ), + } + + let ty = &input.ident; + let ret = quote! { + impl ::rustpython_vm::pyobject::PyStructSequence for #ty { + const FIELD_NAMES: &'static [&'static str] = &[#(stringify!(#field_names)),*]; + fn to_tuple(&self, vm: &::rustpython_vm::VirtualMachine,) -> ::rustpython_vm::obj::objtuple::PyTuple { + let items = vec![#(::rustpython_vm::pyobject::IntoPyObject::into_pyobject( + ::std::clone::Clone::clone(&self.#field_names), + vm, + )),*]; + items.into() + } + } + }; + Ok(ret) +}