mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Move the PyStructSequence impl to a separate mod
This commit is contained in:
3 files changed
+66
-62
No files matched your search
+2
-1
@@ -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
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
Reference in new issue
Block a user