chikatetsu

Crates.iochikatetsu
lib.rschikatetsu
version0.1.0
sourcesrc
created_at2021-01-31 03:29:51.665816
updated_at2021-01-31 03:29:51.665816
descriptionAn(other) actor framework for Tokio
homepage
repositoryhttps://github.com/EthanYidong/chikatetsu
max_upload_size
id348736
size6,149
(EthanYidong)

documentation

README

chikatetsu

An(other) actor framework for tokio.

Why?

Most other actor frameworks use some form of dyn Any, which is basically telling the compiler, "screw your type checking, I have Boxes".

Instead of using dynamic dispatch, we generate and enum that contains all possible types of messages an actor will handle. This is done automagically through a derive macro, and is handeled behind-the-scenes, so you technically never have to use the generated enum in your code (see example below).

use chikatetsu::prelude::*;

#[derive(PartialEq, Debug)]
pub struct Add(i32, i32);
#[derive(PartialEq, Debug)]
pub struct AddResult(i32);

#[derive(PartialEq, Debug)]
pub struct Subtract(i32, i32);
#[derive(PartialEq, Debug)]
pub struct SubtractResult(i32);

/*
Generated enums:
pub enum MathActorMessages {
    Add(Add),
    Subtract(Subtract),
}

pub enum MathActorReplies {
    AddResult(AddResult),
    SubtractResult(SubtractResult),
}
*/

#[derive(Actor)]
#[handles(Add, AddResult)]
#[handles(Subtract, SubtractResult)]
struct MathActor;

#[async_trait]
impl Handler<Add> for MathActor {
    async fn handle(&mut self, add: Add) -> AddResult {
        AddResult(add.0 + add.1)
    }
}

#[async_trait]
impl Handler<Subtract> for MathActor {
    async fn handle(&mut self, add: Subtract) -> SubtractResult {
        SubtractResult(add.0 - add.1)
    }
}

#[tokio::main]
async fn main() {
    let actor = MathActor.start();

    assert_eq!(AddResult(3), actor.send(Add(1, 2)).await);
    assert_eq!(SubtractResult(-1), actor.send(Subtract(1, 2)).await);
}
Commit count: 4

cargo fmt