use std::sync::Arc;
use std::sync::atomic::Ordering;
use std::time::Duration;
use super::Router;
use crate::handler::BoxHandler;
use crate::handler::Handler;
use crate::middleware::Next;
use crate::responder::Responder;
use crate::types::BoxMiddleware;
use crate::types::Request;
use crate::types::Response;
pub type ErrorHandler = Arc<dyn Fn(Response) -> Response + Send + Sync + 'static>;
impl Router {
pub fn middleware<F, Fut, R>(&self, f: F) -> &Self
where
F: Fn(Request, Next) -> Fut + Clone + Send + Sync + 'static,
Fut: std::future::Future<Output = R> + Send + 'static,
R: Responder + Send + 'static,
{
let mw: BoxMiddleware = Arc::new(move |req, next| {
let fut = f(req, next);
Box::pin(async move { fut.await.into_response() })
});
self.middlewares.rcu(move |current| {
let mut next = Vec::with_capacity(current.len() + 1);
next.extend(current.iter().cloned());
next.push(mw.clone());
Arc::new(next)
});
self.has_global_middleware.store(true, Ordering::Release);
self
}
pub fn fallback<F, Fut, R>(&mut self, handler: F) -> &mut Self
where
F: Fn(Request) -> Fut + Clone + Send + Sync + 'static,
Fut: std::future::Future<Output = R> + Send + 'static,
R: Responder + Send + 'static,
{
self.fallback = Some(BoxHandler::new::<F, (Request,)>(handler));
self
}
pub fn fallback_with_extractors<H, T>(&mut self, handler: H) -> &mut Self
where
H: Handler<T> + Clone + 'static,
{
self.fallback = Some(BoxHandler::new::<H, T>(handler));
self
}
pub fn timeout(&mut self, duration: Duration) -> &mut Self {
self.timeout = Some(duration);
self
}
pub fn timeout_fallback<F, Fut, R>(&mut self, handler: F) -> &mut Self
where
F: Fn(Request) -> Fut + Clone + Send + Sync + 'static,
Fut: std::future::Future<Output = R> + Send + 'static,
R: Responder + Send + 'static,
{
self.timeout_fallback = Some(BoxHandler::new::<F, (Request,)>(handler));
self
}
pub fn error_handler(
&mut self,
handler: impl Fn(Response) -> Response + Send + Sync + 'static,
) -> &mut Self {
self.error_handler = Some(Arc::new(handler));
self
}
pub fn client_error_handler(
&mut self,
handler: impl Fn(Response) -> Response + Send + Sync + 'static,
) -> &mut Self {
self.client_error_handler = Some(Arc::new(handler));
self
}
pub fn use_problem_json(&mut self) -> &mut Self {
let h: ErrorHandler = Arc::new(crate::problem::default_problem_responder);
self.error_handler = Some(h.clone());
self.client_error_handler = Some(h);
self
}
}