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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use axum::response::{Html, IntoResponse};
use serde::Serialize;

use crate::TemplateEngine;

/// Rendered template response
///
/// Responds to the request with the rendered template and
/// `text/plain; charset=utf-8` content-type
///
/// # Usage
///
/// ```
/// # use axum::{response::IntoResponse};
/// # use axum_template::{Render, TemplateEngine};
/// use serde::Serialize;
///
/// #[derive(Serialize)]
/// struct Person { /* */ }
///
/// async fn handler(
///     engine: impl TemplateEngine,
/// ) -> impl IntoResponse {
///     let key = "Template key";
///     let data = Person{ /* */ };
///     Render(key, engine, data)
/// }
/// ```
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Render<K, E, S>(pub K, pub E, pub S);

impl<K, E, S> IntoResponse for Render<K, E, S>
where
    E: TemplateEngine,
    S: Serialize,
    K: AsRef<str>,
{
    fn into_response(self) -> axum::response::Response {
        let Render(key, engine, data) = self;

        let result = engine.render(key.as_ref(), data);

        match result {
            Ok(x) => x.into_response(),
            Err(x) => x.into_response(),
        }
    }
}

/// Rendered Html response
///
/// Responds to the request with the rendered template and
/// `text/html` content-type
///
/// # Usage
///
/// ```
/// # use axum::{response::IntoResponse};
/// # use axum_template::{RenderHtml, TemplateEngine};
/// use serde::Serialize;
///
/// #[derive(Serialize)]
/// struct Person { /* */ }
///
/// async fn handler(
///     engine: impl TemplateEngine,
/// ) -> impl IntoResponse {
///     let key = "Template key";
///     let data = Person{ /* */ };
///     RenderHtml(key, engine, data)
/// }
/// ```
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RenderHtml<K, E, S>(pub K, pub E, pub S);

impl<K, E, S> IntoResponse for RenderHtml<K, E, S>
where
    E: TemplateEngine,
    S: Serialize,
    K: AsRef<str>,
{
    fn into_response(self) -> axum::response::Response {
        let RenderHtml(key, engine, data) = self;

        let result = engine.render(key.as_ref(), data);

        match result {
            Ok(x) => Html(x).into_response(),
            Err(x) => x.into_response(),
        }
    }
}

impl<K, E, S> From<Render<K, E, S>> for RenderHtml<K, E, S> {
    fn from(r: Render<K, E, S>) -> Self {
        let Render(a, b, c) = r;
        Self(a, b, c)
    }
}

impl<K, E, S> From<RenderHtml<K, E, S>> for Render<K, E, S> {
    fn from(r: RenderHtml<K, E, S>) -> Self {
        let RenderHtml(a, b, c) = r;
        Self(a, b, c)
    }
}

impl<K, E, S> From<(K, E, S)> for Render<K, E, S> {
    fn from((k, e, s): (K, E, S)) -> Self {
        Self(k, e, s)
    }
}

impl<K, E, S> From<(K, E, S)> for RenderHtml<K, E, S> {
    fn from((k, e, s): (K, E, S)) -> Self {
        Self(k, e, s)
    }
}