如何从以前的宏生成代码生成宏?
How do I generate a macro from previous macro-generated code?
为了创建一个由 pyo3 驱动的 Python class 与使用泛型类型的结构一起工作,我想使用包装器来生成不必为每个特定类型。
我创建了一个生成代码的宏,但我需要将我的宏生成的函数注册为 Python 模块的函数。
一种方法是跟踪宏中使用的标识以使用它们并使用另一个宏生成 wrap_pyfunction
,但我找不到任何相关内容。
(当然欢迎任何其他生成代码的方案)
我现在拥有的(简化)代码:
macro_rules! create_python_function {
($name:ident, $objtype:expr) => {
paste!{
#[pyclass(unsendable)]
pub struct [<$name PyIface>] {
obj: GenericStruct<$objtype>,
}
impl [<$name PyIface>]{
pub fn new() -> [<$name PyIface>]{
[<$name PyIface>] {}
}
}
pub fn [<create_object_ $name>]() -> [<$name PyIface>]{
[<$name PyIface>]::new()
}
}
};
}
create_python_function!(name, SpecificType);
#[pymodule]
fn mymodule(_py: Python, m: &PyModule) -> PyResult<()> {
/* I want to auto-generate this with macro
* m.add_function(wrap_pyfunction!(create_object_name, m)?).unwrap();
*/
Ok(())
}
宏不能共享它们的参数或状态。
如果您不想重复标识符,请将 mymodule
定义移至 create_python_function
宏并将宏更改为使用 repetitions (The Rust Reference)
macro_rules! create_python_function {
($($name:ident => $objtype:ty),* $(,)?) => {
$(
paste! {
#[pyclass(unsendable)]
pub struct [<$name PyIface>] {
obj: GenericStruct<$objtype>,
}
impl [<$name PyIface>]{
pub fn new() -> [<$name PyIface>]{
[<$name PyIface>] { obj: todo!() }
}
}
pub fn [<create_object_ $name>]() -> [<$name PyIface>]{
[<$name PyIface>]::new()
}
}
)*
#[pymodule]
fn mymodule(_py: Python, m: &PyModule) -> Result<(), ()> {
$(
paste! {
m.add_function(wrap_pyfunction!([<create_object_ $name>], m)?).unwrap();
}
)*
Ok(())
}
};
}
struct Foo;
create_python_function!(
foo => Foo,
v => Vec<()>,
);
为了创建一个由 pyo3 驱动的 Python class 与使用泛型类型的结构一起工作,我想使用包装器来生成不必为每个特定类型。
我创建了一个生成代码的宏,但我需要将我的宏生成的函数注册为 Python 模块的函数。
一种方法是跟踪宏中使用的标识以使用它们并使用另一个宏生成 wrap_pyfunction
,但我找不到任何相关内容。
(当然欢迎任何其他生成代码的方案)
我现在拥有的(简化)代码:
macro_rules! create_python_function {
($name:ident, $objtype:expr) => {
paste!{
#[pyclass(unsendable)]
pub struct [<$name PyIface>] {
obj: GenericStruct<$objtype>,
}
impl [<$name PyIface>]{
pub fn new() -> [<$name PyIface>]{
[<$name PyIface>] {}
}
}
pub fn [<create_object_ $name>]() -> [<$name PyIface>]{
[<$name PyIface>]::new()
}
}
};
}
create_python_function!(name, SpecificType);
#[pymodule]
fn mymodule(_py: Python, m: &PyModule) -> PyResult<()> {
/* I want to auto-generate this with macro
* m.add_function(wrap_pyfunction!(create_object_name, m)?).unwrap();
*/
Ok(())
}
宏不能共享它们的参数或状态。
如果您不想重复标识符,请将 mymodule
定义移至 create_python_function
宏并将宏更改为使用 repetitions (The Rust Reference)
macro_rules! create_python_function {
($($name:ident => $objtype:ty),* $(,)?) => {
$(
paste! {
#[pyclass(unsendable)]
pub struct [<$name PyIface>] {
obj: GenericStruct<$objtype>,
}
impl [<$name PyIface>]{
pub fn new() -> [<$name PyIface>]{
[<$name PyIface>] { obj: todo!() }
}
}
pub fn [<create_object_ $name>]() -> [<$name PyIface>]{
[<$name PyIface>]::new()
}
}
)*
#[pymodule]
fn mymodule(_py: Python, m: &PyModule) -> Result<(), ()> {
$(
paste! {
m.add_function(wrap_pyfunction!([<create_object_ $name>], m)?).unwrap();
}
)*
Ok(())
}
};
}
struct Foo;
create_python_function!(
foo => Foo,
v => Vec<()>,
);