Puppet - A simple actor framework

Puppet is yet another actor framework built without any boxing or dynamic dispatch of items, instead it uses a small macro to essentially generate the boilerplate for an enum-based system.

Features

Basic Example

Let's create a small actor for creating hello messages...

```rust use puppet::{puppet_actor, ActorMailbox, Message};

pub struct MyActor;

[puppet_actor]

impl MyActor { #[puppet] async fn onsayhello(&self, msg: SayHello) -> String { format!("Hello, {}!", msg.name) } }

pub struct SayHello { name: String } impl Message for SayHello { type Output = String; }

[tokio::main]

async fn main() { // Create the actor. let actor = MyActor;

// Spawn it on the current runtime, which returns to us a mailbox which
// we can use to communicate with the actor.
let mailbox: ActorMailbox<MyActor> = actor.spawn_actor().await;

let message = SayHello {
    name: "Harri".to_string(),
};

// Send a message to the actor and wait for a response.
let response = mailbox.send(message).await;
println!("Got message back! {}", response);

} ```

Generic Example

Now what if we want to do some more advanced things with our actors? Well luckily for us, we can use generics.

```rust use puppet::{puppet_actor, ActorMailbox, Message};

pub struct AppenderService { seen_data: Vec, }

[puppet_actor]

impl AppenderService where // The additional Send and 'static bounds are required due to the nature // of the actor running as a tokio task which has it's own requirements. T: Clone + Send + 'static, { fn new() -> Self { Self { seen_data: Vec::new(), } }

#[puppet]
async fn on_append_and_return(&mut self, msg: AppendAndReturn<T>) -> Vec<T> {
    self.seen_data.push(msg.value);
    self.seen_data.clone()
}

}

[derive(Clone)]

pub struct AppendAndReturn { value: T, } impl Message for AppendAndReturn where T: Clone, { type Output = Vec; }

[tokio::main]

async fn main() { let actor = AppenderService::::new(); let mailbox: ActorMailbox> = actor.spawn_actor().await;

let message = AppendAndReturn {
    value: "Harri".to_string(),
};

for _ in 0..3 {
    let response = mailbox.send(message.clone()).await;
    println!("Got values: {:?}", response);
}

} ```