use theatre::prelude::*;

#[derive(Default)]
struct Accumulator {
    count: i32,
}

impl Actor for Accumulator {}

struct Increment;

impl Message for Increment {
    type Return = ();
}

struct GetCount;

impl Message for GetCount {
    type Return = i32;
}

#[async_trait]
impl Handler<Increment> for Accumulator {
    async fn handle(
        &mut self,
        _msg: Increment,
        _context: &mut Context<Self>,
    ) -> <Increment as Message>::Return {
        println!("Adding 1");
        self.count += 1
    }
}

#[async_trait]
impl Handler<GetCount> for Accumulator {
    async fn handle(
        &mut self,
        _msg: GetCount,
        _context: &mut Context<Self>,
    ) -> <GetCount as Message>::Return {
        self.count
    }
}

#[tokio::main]
async fn main() {
    let mut acc = Accumulator::default().spawn().await;

    assert_eq!(0, acc.send(GetCount).await.unwrap());

    acc.send(Increment).await.unwrap();
    acc.send(Increment).await.unwrap();
    acc.send(Increment).await.unwrap();
    acc.send(Increment).await.unwrap();

    println!("Value: {}", acc.send(GetCount).await.unwrap());
    assert_eq!(4, acc.send(GetCount).await.unwrap());
}
