Я бы тут не парился, и превращал бы это:
#[r]
fn bar(a: usize) -> usize {
if a % 2 == 0 {
return 0;
}
1
}
В это:
fn bar(a: usize, res: *mut usize) {
fn bar_impl(a: usize) -> usize {
if a % 2 == 0 {
return 0;
}
1
}
unsafe { *res = bar_impl(a); }
}
Главная фишка в том, что исходный код оставляем без изменений, парсить надо только сигнатуру (что с использованием syn - легко).
По сути просто генерируем обёртку. Для универсальности стоит учесть async fn.
Ну и если совсем по хорошему, то тут легко UB поймать с сырым указателем, и генерируемую функцию имеет смысл делать unsafe.