| Crates.io | dsl-ractor |
| lib.rs | dsl-ractor |
| version | 0.2.1 |
| created_at | 2025-09-09 20:19:19.71713+00 |
| updated_at | 2025-11-27 00:02:17.978744+00 |
| description | Reduce boilerplate when working with the Ractor actor framework |
| homepage | https://github.com/irregularBismuth/dsl-ractor |
| repository | https://github.com/irregularBismuth/dsl-ractor |
| max_upload_size | |
| id | 1831475 |
| size | 30,543 |
A simple procedural macro DSL for the Ractor actor framework.
It reduces boilerplate so you can focus on your actor logic and ship faster.
Most Ractor actors repeat the same boilerplate: implementing Actor, defining pre_start,
and wiring handle. This crate generates it so you only write the logic that matters.
#[actor] attribute to auto-generate ractor::Actor implementationsactor_pre_start! for pre_start methodactor_handle! for handle methodargs defaults to () if you omit it in the attributeuse anyhow::Result;
use dsl_ractor::actor;
use ractor::{cast, Actor, ActorRef};
#[derive(Debug, Clone)]
enum CounterMsg {
Increment,
Decrement,
Print,
}
// Define the types `msg`, `state`, `args`
#[actor(msg = CounterMsg, state = i16, args = i16)]
pub struct CounterActor;
impl CounterActor {
// Initialize state from args
dsl_ractor::actor_pre_start!(
Ok(args)
);
// Handle messages, mutate state
dsl_ractor::actor_handle!({
match msg {
CounterMsg::Increment => {
*state = state.saturating_add(1);
Ok(())
}
CounterMsg::Decrement => {
*state = state.saturating_sub(1);
Ok(())
}
CounterMsg::Print => {
println!("[Counter] value = {}", *state);
Ok(())
}
}
});
}
#[tokio::main]
async fn main() -> Result<()> {
// Start counter at 5
let (counter_ref, _handle) = Actor::spawn(None, CounterActor, 5_i16).await?;
cast!(counter_ref, CounterMsg::Increment)?;
cast!(counter_ref, CounterMsg::Increment)?;
cast!(counter_ref, CounterMsg::Decrement)?;
cast!(counter_ref, CounterMsg::Print)?;
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
Ok(())
}