use std::borrow::Cow;
use std::sync::Arc;
use feather_runtime::Method;
use feather_runtime::http::{Request, Response};
use super::route_methods;
use crate::internals::app::Route;
use crate::middlewares::Middleware;
use crate::{AppContext, MiddlewareResult, Outcome};
pub struct Router {
pub(crate) routes: Vec<Route>,
pub(crate) middleware: Vec<Arc<dyn Middleware>>,
}
impl Router {
pub fn new() -> Self {
Self {
routes: Vec::new(),
middleware: Vec::new(),
}
}
pub fn use_middleware<M: Middleware + 'static>(&mut self, mw: M) {
self.middleware.push(Arc::new(mw));
}
pub fn route<M: Middleware + 'static>(&mut self, method: Method, path: impl Into<Cow<'static, str>>, mw: M) {
self.routes.push(Route {
method,
path: path.into(),
middleware: Arc::new(mw),
});
}
route_methods!(
GET get
POST post
PUT put
DELETE delete
PATCH patch
HEAD head
OPTIONS options
);
}
pub(crate) struct ScopedMiddleware {
pub router_stack: Vec<Arc<dyn Middleware>>,
pub route_handler: Arc<dyn Middleware>,
}
impl Middleware for ScopedMiddleware {
fn handle(&self, req: &mut Request, res: &mut Response, ctx: &AppContext) -> Outcome {
for mw in &self.router_stack {
match mw.handle(req, res, ctx)? {
MiddlewareResult::Next => continue,
other => return Ok(other), }
}
self.route_handler.handle(req, res, ctx)
}
}