mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 14:35:36 +01:00
Impl AsyncHandler for SessionDispatcher
This commit is contained in:
parent
6d737dabb4
commit
c98b53b9a8
1 changed files with 48 additions and 32 deletions
|
@ -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"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue