I'm trying to write a derive macro to implement the manager pattern in tokio (https://tokio.rs/tokio/tutorial/shared-state#strategies).
I'm envisioning something like this:
#[derive(Handle)]
pub struct MyData {
x: isize
}
impl MyData {
#[handle]
fn increment(&mut self) {
self.x += 1;
}
#[handle]
fn decrement(&mut self) {
self.x -= 1;
}
#[handle]
fn value(&self) -> isize {
self.x
}
fn do_something_private(&mut self) {
self.x = self.x * self.x;
}
}
that expands to something like this (barring any compilation errors... i haven't actually tried to compile this):
pub struct MyData {
x: isize
}
pub enum MyDataMessage {
Increment,
Decrement,
Value(tokio::sync::oneshot::Sender<isize>),
}
#[derive(Clone)]
pub struct MyDataHandle {
tx: mpsc::Sender<MyDataMessage>
}
impl MyDataHandle {
pub async fn increment(&mut self) {
self.tx.send(MyDataMessage::Increment).await;
}
pub async fn decrement(&mut self) {
self.tx.send(MyDataMessage::Increment).await;
}
pub async fn value(&mut self) -> Result<isize, Box<dyn std::error::Error>> {
let (tx, mut rx) = oneshot::channel();
self.tx.send(MyDataMessage::Value(tx)).await;
rx.await
}
}
impl MyData {
fn increment(&mut self) {
self.x += 1;
}
fn decrement(&mut self) {
self.x -= 1;
}
fn value(&self) -> isize {
self.x
}
fn do_something_private(&mut self) {
self.x = self.x * self.x;
}
}
To break this down, I need to:
- Generate a {name}Handle type from a derive -- OK
- Build an enum based on attribute macros on functions in an impl -- no idea
- Create methods on a generated type based on attribute macros -- no idea
How can I "collect" the items the attribute macro is used on to generate both the enum variants and methods on the Handle
struct?