rstml_component_axum/
lib.rs

1// only enables the `doc_cfg` feature when
2// the `docsrs` configuration attribute is defined
3#![cfg_attr(docsrs, feature(doc_cfg))]
4
5use axum::{http::StatusCode, response::IntoResponse};
6use axum_extra::{headers::ContentType, TypedHeader};
7use rstml_component::{HtmlContent, HtmlFormatter};
8
9pub struct Html<C>(pub C);
10
11impl<C> Html<C>
12where
13	C: FnOnce(&mut HtmlFormatter) -> std::fmt::Result,
14{
15	pub fn from_fn(f: C) -> Self {
16		Html(f)
17	}
18}
19
20impl<C: HtmlContent> From<C> for Html<C> {
21	fn from(value: C) -> Self {
22		Self(value)
23	}
24}
25
26impl<C: HtmlContent> HtmlContent for Html<C> {
27	fn fmt(self, formatter: &mut HtmlFormatter) -> std::fmt::Result {
28		self.0.fmt(formatter)
29	}
30}
31
32impl<C: HtmlContent> IntoResponse for Html<C> {
33	fn into_response(self) -> axum::response::Response {
34		match self.0.into_bytes() {
35			Ok(bytes) => (TypedHeader(ContentType::html()), bytes).into_response(),
36			Err(_e) => (StatusCode::INTERNAL_SERVER_ERROR, "Internal Server Error").into_response(),
37		}
38	}
39}
40
41pub trait HtmlContentAxiosExt: Sized {
42	fn into_html(self) -> Html<Self>;
43
44	fn into_response(self) -> axum::response::Response;
45}
46
47impl<C: HtmlContent> HtmlContentAxiosExt for C {
48	fn into_html(self) -> Html<Self> {
49		Html(self)
50	}
51
52	fn into_response(self) -> axum::response::Response {
53		IntoResponse::into_response(self.into_html())
54	}
55}