5个不稳定版本

0.3.0 2022年12月12日
0.2.0 2022年12月11日
0.1.2 2022年12月7日
0.1.1 2022年12月5日
0.1.0 2022年12月5日

#puppet中排名6

Download history 28/week @ 2024-03-14 21/week @ 2024-03-21 44/week @ 2024-03-28 23/week @ 2024-04-04 15/week @ 2024-04-11 15/week @ 2024-04-18 15/week @ 2024-04-25 13/week @ 2024-05-02 16/week @ 2024-05-09 18/week @ 2024-05-16 20/week @ 2024-05-23 26/week @ 2024-05-30 11/week @ 2024-06-06 17/week @ 2024-06-13 22/week @ 2024-06-20 9/week @ 2024-06-27

每月下载量62
7个crate中使用(通过puppet

MIT许可

33KB
717 代码行

Puppet - 一个简单的演员框架

Puppet是一个没有使用任何装箱或动态分派项的演员框架,它使用一个小宏来生成基于枚举系统的模板代码。

特性

  • 泛型感知,这意味着您可以让泛型演员返回泛型消息。
  • 无装箱,不需要async_trait或装箱进行动态分派。
  • 代码检查友好,您的编辑器应该能够轻松推断所有公开方法的返回类型。
  • 同步和异步邮箱方法。

基本示例

让我们创建一个用于创建hello消息的小演员...

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

pub struct MyActor;

#[puppet_actor]
impl MyActor {
    #[puppet]
    async fn on_say_hello(&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);
}

泛型示例

现在如果我们想对我们的演员做一些更高级的事情怎么办?幸运的是,我们可以使用泛型。

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

pub struct AppenderService<T: Clone> {
    seen_data: Vec<T>,
}

#[puppet_actor]
impl<T> AppenderService<T>
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<T: Clone> {
    value: T,
}
impl<T> Message for AppendAndReturn<T>
where
    T: Clone,
{
    type Output = Vec<T>;
}

#[tokio::main]
async fn main() {
    let actor = AppenderService::<String>::new();
    let mailbox: ActorMailbox<AppenderService<String>> = 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);
    }
}

依赖项

~2MB
~45K SLoC