Как сгенерировать макрос из предыдущего кода, сгенерированного макросом?
Чтобы создать класс Python на основе pyo3, работающий со структурой, использующей универсальный тип, я хочу использовать оболочки, которые будут генерировать код, необходимый для того, чтобы не делать это для каждого конкретного типа.
Я создал макрос, который генерирует код, но мне нужно зарегистрировать функции, сгенерированные моим макросом, как функции модуля 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(())
}
1 ответ
Макросы не могут делиться своими аргументами или состояниями. Если вы не хотите повторять идентификаторы, переместите
mymodule
определение в
create_python_function
макрос и измените макрос, чтобы использовать повторения (Справочник по Rust)
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<()>,
);