use super::Piece;
use crate::http::header::{HeaderValue, CONTENT_TYPE};
use crate::http::Response;
#[non_exhaustive]
pub enum Text<C> {
Plain(C),
Json(C),
Xml(C),
Html(C),
Js(C),
Css(C),
Csv(C),
Atom(C),
Rss(C),
Rdf(C),
}
impl<C> Text<C>
where
C: AsRef<str>,
{
fn set_header(self, res: &mut Response) -> C {
let (ctype, content) = match self {
Self::Plain(content) => (HeaderValue::from_static("text/plain; charset=utf-8"), content),
Self::Json(content) => (HeaderValue::from_static("application/json; charset=utf-8"), content),
Self::Xml(content) => (HeaderValue::from_static("application/xml; charset=utf-8"), content),
Self::Html(content) => (HeaderValue::from_static("text/html; charset=utf-8"), content),
Self::Js(content) => (HeaderValue::from_static("text/javascript; charset=utf-8"), content),
Self::Css(content) => (HeaderValue::from_static("text/css; charset=utf-8"), content),
Self::Csv(content) => (HeaderValue::from_static("text/csv; charset=utf-8"), content),
Self::Atom(content) => (HeaderValue::from_static("application/atom+xml; charset=utf-8"), content),
Self::Rss(content) => (HeaderValue::from_static("application/rss+xml; charset=utf-8"), content),
Self::Rdf(content) => (HeaderValue::from_static("application/rdf+xml; charset=utf-8"), content),
};
res.headers_mut().insert(CONTENT_TYPE, ctype);
content
}
}
impl Piece for Text<&'static str> {
#[inline]
fn render(self, res: &mut Response) {
let content = self.set_header(res);
res.write_body(content).ok();
}
}
impl Piece for Text<String> {
#[inline]
fn render(self, res: &mut Response) {
let content = self.set_header(res);
res.write_body(content).ok();
}
}
impl<'a> Piece for Text<&'a String> {
#[inline]
fn render(self, res: &mut Response) {
let content = self.set_header(res);
res.write_body(content.as_bytes().to_vec()).ok();
}
}
#[cfg(test)]
mod tests {
use crate::prelude::*;
use super::*;
use crate::test::{ResponseExt, TestClient};
#[tokio::test]
async fn test_write_str() {
#[handler(internal)]
async fn test() -> &'static str {
"hello"
}
let router = Router::new().push(Router::with_path("test").get(test));
let mut res = TestClient::get("http://127.0.0.1:7878/test").send(router).await;
assert_eq!(res.take_string().await.unwrap(), "hello");
assert_eq!(res.headers().get("content-type").unwrap(), "text/plain; charset=utf-8");
}
#[tokio::test]
async fn test_write_string() {
#[handler(internal)]
async fn test() -> String {
"hello".to_owned()
}
let router = Router::new().push(Router::with_path("test").get(test));
let mut res = TestClient::get("http://127.0.0.1:7878/test").send(router).await;
assert_eq!(res.take_string().await.unwrap(), "hello");
assert_eq!(res.headers().get("content-type").unwrap(), "text/plain; charset=utf-8");
}
#[tokio::test]
async fn test_write_plain_text() {
#[handler(internal)]
async fn test() -> Text<&'static str> {
Text::Plain("hello")
}
let router = Router::new().push(Router::with_path("test").get(test));
let mut res = TestClient::get("http://127.0.0.1:7878/test").send(router).await;
assert_eq!(res.take_string().await.unwrap(), "hello");
assert_eq!(res.headers().get("content-type").unwrap(), "text/plain; charset=utf-8");
}
#[tokio::test]
async fn test_write_json_text() {
#[handler(internal)]
async fn test() -> Text<&'static str> {
Text::Json(r#"{"hello": "world"}"#)
}
let router = Router::new().push(Router::with_path("test").get(test));
let mut res = TestClient::get("http://127.0.0.1:7878/test").send(router).await;
assert_eq!(res.take_string().await.unwrap(), r#"{"hello": "world"}"#);
assert_eq!(
res.headers().get("content-type").unwrap(),
"application/json; charset=utf-8"
);
}
#[tokio::test]
async fn test_write_html_text() {
#[handler(internal)]
async fn test() -> Text<&'static str> {
Text::Html("<html><body>hello</body></html>")
}
let router = Router::new().push(Router::with_path("test").get(test));
let mut res = TestClient::get("http://127.0.0.1:7878/test").send(router).await;
assert_eq!(res.take_string().await.unwrap(), "<html><body>hello</body></html>");
assert_eq!(res.headers().get("content-type").unwrap(), "text/html; charset=utf-8");
}
}