bitbroker 0.0.1-alpha

A language agnostic message broker designed for real-time communication.
Documentation
use std::future::Future;

use crate::{proto::InitialMessageBatchProto, Action, BitBrokerMessage, Connection, Result};

pub trait BaseGame {
    type State: Into<Vec<u8>>;
    type Response<'a>: From<&'a [u8]>;

    fn initialise(
        &mut self,
        initial_info: InitialMessageBatchProto,
    ) -> impl Future<Output = ()> + Send;
    fn next_action(&mut self) -> impl Future<Output = Action<Self::State>> + Send;
    fn deliver_response<'a>(
        &mut self,
        response: Self::Response<'a>,
    ) -> impl Future<Output = ()> + Send;
}

pub async fn run_game<G>(game: &mut G, host: &str, port: usize) -> Result<()>
where
    G: BaseGame,
{
    let mut connection = Connection::new(host, port).await?;
    connection
        .send_message(BitBrokerMessage::initial_game_message())
        .await
        .unwrap();

    let initial_message: BitBrokerMessage = connection.read_message().await?;
    match initial_message.codes() {
        (0x00, 0x11) => game.initialise(initial_message.body_proto()?).await,
        _ => return Err(initial_message.into()),
    }

    loop {
        let message: BitBrokerMessage = connection.read_message().await?;
        match message.codes() {
            (0x00, 0xFF) => return Ok(()),
            (0x01, 0x00) => {
                let action = game.next_action().await;
                let has_response = action.has_response();
                connection
                    .send_message(BitBrokerMessage::from(action))
                    .await?;

                if has_response {
                    let response: BitBrokerMessage = connection.read_message().await?;
                    game.deliver_response(response.body().into()).await;
                }
            }
            _ => return Err(initial_message.into()),
        }
    }
}