rocket/response/content.rs
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
//! Contains types that set the Content-Type of a response.
//!
//! # Usage
//!
//! Each type in this module is a `Responder` that wraps an existing
//! `Responder`, overwriting the `Content-Type` of the response but otherwise
//! delegating the response to the wrapped responder. As a convenience,
//! `(ContentType, R)` where `R: Responder` is _also_ a `Responder` that
//! overrides the `Content-Type` to the value in `.0`:
//!
//! ```rust
//! # use rocket::get;
//! use rocket::http::ContentType;
//!
//! #[get("/")]
//! fn index() -> (ContentType, &'static str) {
//! (ContentType::HTML, "Is this HTML? <p>Sure, why not!</p>")
//! }
//! ```
//!
//! # Example
//!
//! The following snippet creates a `RawHtml` response from a string. Normally,
//! raw strings set their response Content-Type to `text/plain`. By using the
//! `RawHtml` content response, the Content-Type will be set to `text/html`
//! instead:
//!
//! ```rust
//! use rocket::response::content;
//!
//! let response = content::RawHtml("<h1>Hello, world!</h1>");
//! ```
use crate::request::Request;
use crate::response::{self, Response, Responder};
use crate::http::ContentType;
macro_rules! ctrs {
($($name:ident: $ct:ident, $name_str:expr, $ct_str:expr),+) => {
$(
#[doc="Override the `Content-Type` of the response to <b>"]
#[doc=$name_str]
#[doc="</b>, or <i>"]
#[doc=$ct_str]
#[doc="</i>."]
///
/// Delegates the remainder of the response to the wrapped responder.
///
/// **Note:** Unlike types like [`Json`](crate::serde::json::Json)
/// and [`MsgPack`](crate::serde::msgpack::MsgPack), this type _does
/// not_ serialize data in any way. You should _always_ use those
/// types to respond with serializable data. Additionally, you
/// should _always_ use [`NamedFile`](crate::fs::NamedFile), which
/// automatically sets a `Content-Type`, to respond with file data.
#[derive(Debug, Clone, PartialEq)]
pub struct $name<R>(pub R);
/// Sets the Content-Type of the response then delegates the
/// remainder of the response to the wrapped responder.
impl<'r, 'o: 'r, R: Responder<'r, 'o>> Responder<'r, 'o> for $name<R> {
fn respond_to(self, req: &'r Request<'_>) -> response::Result<'o> {
(ContentType::$ct, self.0).respond_to(req)
}
}
)+
}
}
ctrs! {
// FIXME: Add a note that this is _not_ `serde::Json`.
RawJson: JSON, "JSON", "application/json",
RawXml: XML, "XML", "text/xml",
RawMsgPack: MsgPack, "MessagePack", "application/msgpack",
RawHtml: HTML, "HTML", "text/html",
RawText: Text, "plain text", "text/plain",
RawCss: CSS, "CSS", "text/css",
RawJavaScript: JavaScript, "JavaScript", "application/javascript"
}
impl<'r, 'o: 'r, R: Responder<'r, 'o>> Responder<'r, 'o> for (ContentType, R) {
fn respond_to(self, req: &'r Request<'_>) -> response::Result<'o> {
Response::build()
.merge(self.1.respond_to(req)?)
.header(self.0)
.ok()
}
}