rustybook-messenger 0.2.1

Messenger client for Rustybook
Documentation
use async_trait::async_trait;

use crate::client::context::Context;
use crate::client::models::*;
use crate::gateway::events::*;

#[derive(Debug, Clone)]
pub struct ErrorEvent {
    pub kind: String,
    pub message: String,
}

macro_rules! event_handler {
    (
        $(
            $(#[$meta:meta])*
            fn $name:ident(&self $(, $arg:ident : $arg_ty:ty )* );
        )*
    ) => {
        #[async_trait]
        pub trait EventHandler: Send + Sync + 'static {
            $(
                $(#[$meta])*
                async fn $name(&self $(, $arg: $arg_ty)*) {}
            )*
        }
    };
}

macro_rules! emit_event {
    ($handler:expr, $method:ident, $ctx:expr) => {
        $handler.$method($ctx.clone()).await;
    };
    ($handler:expr, $method:ident, $ctx:expr, $value:expr) => {
        $handler.$method($ctx.clone(), $value).await;
    };
}

event_handler! {
    /// Called when messenger listener is ready.
    fn ready(&self, _ctx: Context, _user: User);

    /// Called when a message event is received.
    fn message(&self, _ctx: Context, _msg: Message);

    /// Called when a typing event is received.
    fn typing(&self, _ctx: Context, _typing: Typing);

    /// Called when a presence event is received.
    fn presence(&self, _ctx: Context, _presence: Presence);

    /// Called when the messenger listener disconnects.
    fn disconnect(&self, _ctx: Context);

    /// Called when the messenger runtime emits an error event.
    fn error(&self, _ctx: Context, _error: ErrorEvent);
}

pub(crate) async fn dispatch_event(
    handler: &dyn EventHandler,
    ctx: Context,
    ready_user: &User,
    event: Event,
) {
    match event {
        Event::Listening => {
            emit_event!(handler, ready, ctx, ready_user.clone());
        }
        Event::Disconnect => {
            emit_event!(handler, disconnect, ctx);
        }
        Event::Message(message) => {
            emit_event!(handler, message, ctx, (&message).into());
        }
        Event::Typing(typing) => {
            emit_event!(
                handler,
                typing,
                ctx,
                Typing {
                    user_id: typing.user_id,
                    thread_id: typing.thread_id,
                    is_typing: typing.is_typing,
                }
            );
        }
        Event::Presence(presence) => {
            emit_event!(
                handler,
                presence,
                ctx,
                Presence {
                    user_id: presence.user_id,
                    is_active: presence.is_active,
                    last_active_ms: presence.last_active_ms,
                }
            );
        }
        Event::Error(error) => {
            emit_event!(
                handler,
                error,
                ctx,
                ErrorEvent {
                    kind: format!("{:?}", error.kind),
                    message: error.message,
                }
            );
        }
    }
}