aboutsummaryrefslogtreecommitdiffstats
path: root/askama_mendes/tests/basic.rs
blob: 6ab1d6d319cd582e0f8954b6b58e87592574d45e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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<HelloTemplate<'static>, 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<Self>) -> Response<Body> {
        route!(match cx.path() {
            _ => hello,
        })
    }
}

#[derive(Debug)]
enum Error {
    Askama(askama::Error),
    Mendes(mendes::Error),
}

impl From<askama::Error> for Error {
    fn from(e: askama::Error) -> Error {
        Error::Askama(e)
    }
}

impl From<mendes::Error> 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<App> for Error {
    fn into_response(self, _: &App, _: &Parts) -> Response<Body> {
        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,
        }
    }
}