Move the PyStructSequence impl to a separate mod

This commit is contained in:
Noah committed 2020-08-30 15:46:05 -05:00
1 parent 2d49dcd66e
commit 5bc5da8da1
3 files changed
+66 -62

No files matched your search

+2 -1
View File
@@ -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]
+1 -61
View File
@@ -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<TokenStream, Diagnostic> {
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,
+63
View File
@@ -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<TokenStream, Diagnostic> {
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)
}