use crate::http::{Handler, Path, Request, Response, Router};
use super::{AuthHandler, Controller, Error};
#[derive(Default)]
pub struct Engine {
router: Router,
mount: Path,
auth: Option<AuthHandler>,
}
impl Engine {
pub fn new(handlers: Vec<Handler>) -> Self {
Self {
router: Router::new(handlers).unwrap(),
mount: Path::parse("/").unwrap(),
auth: None,
}
}
pub fn remount(mut self, mount: &Path) -> Self {
self.mount = mount.clone();
self
}
pub fn auth(mut self, auth: AuthHandler) -> Self {
self.auth = Some(auth);
self
}
pub fn mount(&self) -> &Path {
&self.mount
}
}
#[crate::async_trait]
impl Controller for Engine {
async fn handle(&self, request: &Request) -> Result<Response, Error> {
if let Some(ref auth) = self.auth {
let auth = auth.auth();
if !auth.authorize(request).await? {
return auth.denied(request).await;
}
}
let path = request.path().pop_base(&self.mount);
let handler = self.router.find(&path);
if let Some(handler) = handler {
handler.handle(request).await
} else {
Ok(Response::not_found())
}
}
}