use crate::{
client::Reqwest,
errors::EventErrorKind,
event::{
service::{service_fn, BoxCloneService},
EventReturn,
},
Request,
};
use std::future::Future;
pub(crate) type BoxedCloneMiddlewareService<Client> =
BoxCloneService<Request<Client>, MiddlewareResponse<Client>, EventErrorKind>;
pub type MiddlewareResponse<Client = Reqwest> = (Request<Client>, EventReturn);
pub trait Middleware<Client = Reqwest>: Clone + Send + Sync + 'static {
fn call(
&mut self,
request: Request<Client>,
) -> impl Future<Output = Result<MiddlewareResponse<Client>, EventErrorKind>> + Send;
}
impl<Client, F, Fut> Middleware<Client> for F
where
Client: Send + Sync + 'static,
F: FnMut(Request<Client>) -> Fut + Clone + Send + Sync + 'static,
Fut: Future<Output = Result<MiddlewareResponse<Client>, EventErrorKind>> + Send,
{
fn call(
&mut self,
request: Request<Client>,
) -> impl Future<Output = Result<MiddlewareResponse<Client>, EventErrorKind>> + Send {
self(request)
}
}
pub(crate) fn boxed_middleware_factory<Client>(
middleware: impl Middleware<Client>,
) -> BoxedCloneMiddlewareService<Client>
where
Client: Send + Sync + 'static,
{
BoxCloneService::new(service_fn(move |request| {
let mut middleware = middleware.clone();
async move { middleware.call(request).await }
}))
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
client::Reqwest,
context::Context,
types::{ChatPrivate, MessageText, Update, UpdateMessage},
Bot, Extensions,
};
use std::sync::Arc;
use tokio;
#[tokio::test]
async fn test_call() {
let mut middleware =
|request: Request<Reqwest>| async move { Ok((request, EventReturn::default())) };
let request = Request::<Reqwest> {
update: Arc::new(Update::Message(UpdateMessage::new(
0,
MessageText::new(0, 0, ChatPrivate::new(0), ""),
))),
bot: Bot::default(),
context: Context::default(),
extensions: Extensions::default(),
};
let (_, event_return) = Middleware::call(&mut middleware, request.clone())
.await
.unwrap();
assert_eq!(event_return, EventReturn::default());
}
}