use std::sync::Arc; use async_trait::async_trait; use hyper::body::to_bytes; use hyper::{Body, Request}; use mendes::application::IntoResponse; use mendes::http::request::Parts; use mendes::http::{Response, StatusCode}; use mendes::{handler, route, Application, Context}; use askama::Template; #[tokio::test] async fn test() { let req = Request::builder().body(()).unwrap(); let rsp = App::handle(Context::new(Arc::new(App), req)).await; let (rsp, body) = rsp.into_parts(); assert_eq!( rsp.headers .get("content-type") .and_then(|hv| hv.to_str().ok()), Some("text/plain; charset=utf-8") ); assert_eq!(to_bytes(body).await.unwrap(), &b"Hello, world!"[..]); } #[handler(GET)] async fn hello(_: &App) -> Result, Error> { Ok(HelloTemplate { name: "world" }) } #[derive(Template)] #[template(path = "hello.txt")] struct HelloTemplate<'a> { name: &'a str, } struct App; #[async_trait] impl Application for App { type RequestBody = (); type ResponseBody = Body; type Error = Error; async fn handle(mut cx: Context) -> Response { route!(match cx.path() { _ => hello, }) } } #[derive(Debug)] enum Error { Askama(askama::Error), Mendes(mendes::Error), } impl From for Error { fn from(e: askama::Error) -> Error { Error::Askama(e) } } impl From for Error { fn from(e: mendes::Error) -> Error { Error::Mendes(e) } } impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Error::Askama(e) => write!(f, "{e}"), Error::Mendes(e) => write!(f, "{e}"), } } } impl IntoResponse for Error { fn into_response(self, _: &App, _: &Parts) -> Response { Response::builder() .status(StatusCode::from(&self)) .body(self.to_string().into()) .unwrap() } } impl From<&Error> for StatusCode { fn from(e: &Error) -> StatusCode { match e { Error::Mendes(e) => StatusCode::from(e), Error::Askama(_) => StatusCode::INTERNAL_SERVER_ERROR, } } }