Impl AsyncHandler for SessionDispatcher

This commit is contained in:
Temirkhan Myrzamadi 2020-01-30 01:10:02 +06:00
parent 6d737dabb4
commit c98b53b9a8

View file

@ -34,15 +34,22 @@ mod storage;
use crate::{dispatching::AsyncHandler, Bot}; use crate::{dispatching::AsyncHandler, Bot};
pub use get_chat_id::*; pub use get_chat_id::*;
use std::{future::Future, pin::Pin, sync::Arc};
pub use storage::*; pub use storage::*;
/// A context of a private message handler. /// A context of a private message handler.
pub struct SessionHandlerCtx<'a, Upd, Session> { pub struct SessionHandlerCtx<Upd, Session> {
pub bot: &'a Bot, pub bot: Arc<Bot>,
pub update: Upd, pub update: Upd,
pub session: Session, pub session: Session,
} }
/// A context of a session dispatcher.
pub struct SessionDispatcherCtx<Upd> {
pub bot: Arc<Bot>,
pub update: Upd,
}
/// Continue or terminate a user session. /// Continue or terminate a user session.
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)] #[derive(Debug, Copy, Clone, Eq, Hash, PartialEq)]
pub enum SessionState<Session> { pub enum SessionState<Session> {
@ -83,44 +90,53 @@ where
handler, handler,
} }
} }
}
impl<'a, Session, H, Upd> AsyncHandler<SessionDispatcherCtx<Upd>, ()>
for SessionDispatcher<'a, Session, H>
where
H: AsyncHandler<SessionHandlerCtx<Upd, Session>, SessionState<Session>>,
Upd: GetChatId,
Session: Default,
{
/// Dispatches a single `message` from a private chat. /// Dispatches a single `message` from a private chat.
pub async fn dispatch<Upd>(&'a self, bot: &'a Bot, update: Upd) fn handle<'b>(
&'b self,
ctx: SessionDispatcherCtx<Upd>,
) -> Pin<Box<dyn Future<Output = ()> + 'b>>
where where
H: AsyncHandler< Upd: 'b,
SessionHandlerCtx<'a, Upd, Session>,
SessionState<Session>,
>,
Upd: GetChatId,
{ {
let chat_id = update.chat_id(); Box::pin(async move {
let chat_id = ctx.update.chat_id();
let session = self let session = self
.storage
.remove_session(chat_id)
.await
.unwrap_or_default();
if let SessionState::Continue(new_session) = self
.handler
.handle(SessionHandlerCtx {
bot,
update,
session,
})
.await
{
if self
.storage .storage
.update_session(chat_id, new_session) .remove_session(chat_id)
.await
.unwrap_or_default();
if let SessionState::Continue(new_session) = self
.handler
.handle(SessionHandlerCtx {
bot: ctx.bot,
update: ctx.update,
session,
})
.await .await
.is_some()
{ {
panic!( if self
"We previously storage.remove_session() so \ .storage
storage.update_session() must return None" .update_session(chat_id, new_session)
); .await
.is_some()
{
panic!(
"We previously storage.remove_session() so \
storage.update_session() must return None"
);
}
} }
} })
} }
} }