rocket/response/content.rs
1//! Contains types that set the Content-Type of a response.
2//!
3//! # Usage
4//!
5//! Each type in this module is a `Responder` that wraps an existing
6//! `Responder`, overwriting the `Content-Type` of the response but otherwise
7//! delegating the response to the wrapped responder. As a convenience,
8//! `(ContentType, R)` where `R: Responder` is _also_ a `Responder` that
9//! overrides the `Content-Type` to the value in `.0`:
10//!
11//! ```rust
12//! # use rocket::get;
13//! use rocket::http::ContentType;
14//!
15//! #[get("/")]
16//! fn index() -> (ContentType, &'static str) {
17//! (ContentType::HTML, "Is this HTML? <p>Sure, why not!</p>")
18//! }
19//! ```
20//!
21//! # Example
22//!
23//! The following snippet creates a `RawHtml` response from a string. Normally,
24//! raw strings set their response Content-Type to `text/plain`. By using the
25//! `RawHtml` content response, the Content-Type will be set to `text/html`
26//! instead:
27//!
28//! ```rust
29//! use rocket::response::content;
30//!
31//! let response = content::RawHtml("<h1>Hello, world!</h1>");
32//! ```
33
34use crate::request::Request;
35use crate::response::{self, Response, Responder};
36use crate::http::ContentType;
37
38macro_rules! ctrs {
39 ($($name:ident: $ct:ident, $name_str:expr, $ct_str:expr),+) => {
40 $(
41 #[doc="Override the `Content-Type` of the response to <b>"]
42 #[doc=$name_str]
43 #[doc="</b>, or <i>"]
44 #[doc=$ct_str]
45 #[doc="</i>."]
46 ///
47 /// Delegates the remainder of the response to the wrapped responder.
48 ///
49 /// **Note:** Unlike types like [`Json`](crate::serde::json::Json)
50 /// and [`MsgPack`](crate::serde::msgpack::MsgPack), this type _does
51 /// not_ serialize data in any way. You should _always_ use those
52 /// types to respond with serializable data. Additionally, you
53 /// should _always_ use [`NamedFile`](crate::fs::NamedFile), which
54 /// automatically sets a `Content-Type`, to respond with file data.
55 #[derive(Debug, Clone, PartialEq)]
56 pub struct $name<R>(pub R);
57
58 /// Sets the Content-Type of the response then delegates the
59 /// remainder of the response to the wrapped responder.
60 impl<'r, 'o: 'r, R: Responder<'r, 'o>> Responder<'r, 'o> for $name<R> {
61 fn respond_to(self, req: &'r Request<'_>) -> response::Result<'o> {
62 (ContentType::$ct, self.0).respond_to(req)
63 }
64 }
65 )+
66 }
67}
68
69ctrs! {
70 // FIXME: Add a note that this is _not_ `serde::Json`.
71 RawJson: JSON, "JSON", "application/json",
72 RawXml: XML, "XML", "text/xml",
73 RawMsgPack: MsgPack, "MessagePack", "application/msgpack",
74 RawHtml: HTML, "HTML", "text/html",
75 RawText: Text, "plain text", "text/plain",
76 RawCss: CSS, "CSS", "text/css",
77 RawJavaScript: JavaScript, "JavaScript", "application/javascript"
78}
79
80impl<'r, 'o: 'r, R: Responder<'r, 'o>> Responder<'r, 'o> for (ContentType, R) {
81 fn respond_to(self, req: &'r Request<'_>) -> response::Result<'o> {
82 Response::build()
83 .merge(self.1.respond_to(req)?)
84 .header(self.0)
85 .ok()
86 }
87}