Recognize distributed_slice on functions as a special case
dtolnay opened this issue · comments
David Tolnay commented
Building registries of function pointers is probably the most common use case for distributed_slice.
The benchmark harness use case in the readme is one example, or the following registry of error type conversions for crates to register semantically meaningful conversions into Python errors for their custom error types.
use cpython::{exc, PyErr, Python};
use distributed_slice::distributed_slice;
use std::io;
#[distributed_slice]
pub static INTO_PYERR: [fn(&anyhow::Error, py: Python<'_>) -> Option<PyErr>] = [..];
#[distributed_slice(INTO_PYERR)]
static IO_INTO_PYERR: fn(&anyhow::Error, py: Python<'_>) -> Option<PyErr> = io_into_pyerr;
fn io_into_pyerr(err: &anyhow::Error, py: Python<'_>) -> Option<PyErr> {
let err = err.downcast_ref::<io::Error>()?;
Some(PyErr::new::<exc::IOError, _>(
py,
(e.raw_os_error(), e.to_string()),
))
}
It would be great to handle function pointers as a special case in our attribute macro to allow this more concise invocation:
#[distributed_slice(INTO_PYERR)]
fn io_into_pyerr(err: &anyhow::Error, py: Python<'_>) -> Option<PyErr> {
...
}
which would expand to the pair of IO_INTO_PYERR static + io_into_pyerr function as above.