mirror of https://github.com/rwf2/Rocket.git
Prefix 'content' responder names with 'Raw'.
The primary aim of this commit is to reduce confusion between 'content::Json' and 'rocket::serde::json::Json' be renaming the former to 'content::RawJson'. The complete changes in this PR are: * All responders in the 'content' module are prefixed with 'Raw'. * The 'content::Custom' responder was removed entirely. * The 'Plain' responder is now 'RawText'. * The 'content' API docs point to the 'serde' responders. * The docs and examples were updated accordingly.
This commit is contained in:
parent
179be25866
commit
cc0621626b
|
@ -8,7 +8,8 @@ use crate::request::Request;
|
|||
use crate::response::{self, Responder};
|
||||
use crate::http::ContentType;
|
||||
|
||||
/// A [`Responder`] that sends a file with a Content-Type based on its name.
|
||||
/// A [`Responder`] that sends file data with a Content-Type based on its
|
||||
/// file extension.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
|
|
@ -2,15 +2,11 @@
|
|||
//!
|
||||
//! # Usage
|
||||
//!
|
||||
//! Each type wraps a given responder. The `Responder` implementation of each
|
||||
//! type replaces the Content-Type of the wrapped responder and delegates the
|
||||
//! remainder of the response to the wrapped responder. This allows for setting
|
||||
//! the Content-Type of a type that doesn't set it itself or for overriding one
|
||||
//! that does.
|
||||
//!
|
||||
//! The [`Custom`] type allows responding with _any_ `Content-Type`. As a
|
||||
//! convenience, `(ContentType, R)` where `R: Responder` is _also_ a
|
||||
//! `Responder`, identical to `Custom`.
|
||||
//! 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;
|
||||
|
@ -21,55 +17,24 @@
|
|||
//! (ContentType::HTML, "Is this HTML? <p>Sure, why not!</p>")
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! The following snippet creates an `Html` content response for a string.
|
||||
//! Normally, raw strings set their response Content-Type to `text/plain`. By
|
||||
//! using the `Html` content response, the Content-Type will be set to
|
||||
//! `text/html` instead.
|
||||
//! 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;
|
||||
//!
|
||||
//! # #[allow(unused_variables)]
|
||||
//! let response = content::Html("<h1>Hello, world!</h1>");
|
||||
//! let response = content::RawHtml("<h1>Hello, world!</h1>");
|
||||
//! ```
|
||||
|
||||
use crate::request::Request;
|
||||
use crate::response::{self, Response, Responder};
|
||||
use crate::http::ContentType;
|
||||
|
||||
/// Sets the Content-Type of a `Responder` to a chosen value.
|
||||
///
|
||||
/// Delegates the remainder of the response to the wrapped responder.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Set the Content-Type of a string to PDF.
|
||||
///
|
||||
/// ```rust
|
||||
/// use rocket::response::content::Custom;
|
||||
/// use rocket::http::ContentType;
|
||||
///
|
||||
/// # #[allow(unused_variables)]
|
||||
/// let response = Custom(ContentType::PDF, "Hi.");
|
||||
/// ```
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Custom<R>(pub ContentType, pub R);
|
||||
|
||||
/// Overrides the Content-Type of the response to the wrapped `ContentType` then
|
||||
/// delegates the remainder of the response to the wrapped responder.
|
||||
impl<'r, 'o: 'r, R: Responder<'r, 'o>> Responder<'r, 'o> for Custom<R> {
|
||||
fn respond_to(self, req: &'r Request<'_>) -> response::Result<'o> {
|
||||
Response::build()
|
||||
.merge(self.1.respond_to(req)?)
|
||||
.header(self.0)
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! ctrs {
|
||||
($($name:ident: $ct:ident, $name_str:expr, $ct_str:expr),+) => {
|
||||
$(
|
||||
|
@ -80,6 +45,13 @@ macro_rules! ctrs {
|
|||
#[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);
|
||||
|
||||
|
@ -87,7 +59,7 @@ macro_rules! ctrs {
|
|||
/// 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> {
|
||||
Custom(ContentType::$ct, self.0).respond_to(req)
|
||||
(ContentType::$ct, self.0).respond_to(req)
|
||||
}
|
||||
}
|
||||
)+
|
||||
|
@ -96,18 +68,20 @@ macro_rules! ctrs {
|
|||
|
||||
ctrs! {
|
||||
// FIXME: Add a note that this is _not_ `serde::Json`.
|
||||
Json: JSON, "JSON", "application/json",
|
||||
Xml: XML, "XML", "text/xml",
|
||||
MsgPack: MsgPack, "MessagePack", "application/msgpack",
|
||||
Html: HTML, "HTML", "text/html",
|
||||
Plain: Plain, "plain text", "text/plain",
|
||||
Css: CSS, "CSS", "text/css",
|
||||
JavaScript: JavaScript, "JavaScript", "application/javascript"
|
||||
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) {
|
||||
#[inline(always)]
|
||||
fn respond_to(self, request: &'r Request<'_>) -> response::Result<'o> {
|
||||
Custom(self.0, self.1).respond_to(request)
|
||||
fn respond_to(self, req: &'r Request<'_>) -> response::Result<'o> {
|
||||
Response::build()
|
||||
.merge(self.1.respond_to(req)?)
|
||||
.header(self.0)
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -223,7 +223,7 @@ impl<'r, T: Serialize> Responder<'r, 'static> for Json<T> {
|
|||
Status::InternalServerError
|
||||
})?;
|
||||
|
||||
content::Json(string).respond_to(req)
|
||||
content::RawJson(string).respond_to(req)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,7 +299,7 @@ impl<'v, T: Deserialize<'v> + Send> form::FromFormField<'v> for Json<T> {
|
|||
/// and a fixed-size body with the serialized value.
|
||||
impl<'r> Responder<'r, 'static> for Value {
|
||||
fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> {
|
||||
content::Json(self.to_string()).respond_to(req)
|
||||
content::RawJson(self.to_string()).respond_to(req)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -194,7 +194,7 @@ impl<'r, T: Serialize> Responder<'r, 'static> for MsgPack<T> {
|
|||
Status::InternalServerError
|
||||
})?;
|
||||
|
||||
content::MsgPack(buf).respond_to(req)
|
||||
content::RawMsgPack(buf).respond_to(req)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#[macro_use] extern crate rocket;
|
||||
|
||||
use rocket::{http::Status, response::content};
|
||||
use rocket::http::Status;
|
||||
use rocket::response::content::RawJson;
|
||||
|
||||
#[get("/empty")]
|
||||
fn empty() -> Status {
|
||||
|
@ -13,8 +14,8 @@ fn index() -> &'static str {
|
|||
}
|
||||
|
||||
#[head("/other")]
|
||||
fn other() -> content::Json<&'static str> {
|
||||
content::Json("{ 'hi': 'hello' }")
|
||||
fn other() -> RawJson<&'static str> {
|
||||
RawJson("{ 'hi': 'hello' }")
|
||||
}
|
||||
|
||||
mod head_handling_tests {
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
mod session;
|
||||
mod message;
|
||||
|
||||
use rocket::response::content::Html;
|
||||
use rocket::response::content::RawHtml;
|
||||
use rocket_dyn_templates::Template;
|
||||
|
||||
#[get("/")]
|
||||
fn index() -> Html<&'static str> {
|
||||
Html(r#"<a href="message">Set a Message</a> or <a href="session">Use Sessions</a>."#)
|
||||
fn index() -> RawHtml<&'static str> {
|
||||
RawHtml(r#"<a href="message">Set a Message</a> or <a href="session">Use Sessions</a>."#)
|
||||
}
|
||||
|
||||
#[launch]
|
||||
|
|
|
@ -17,16 +17,16 @@ fn forced_error(code: u16) -> Status {
|
|||
}
|
||||
|
||||
#[catch(404)]
|
||||
fn general_not_found() -> content::Html<&'static str> {
|
||||
content::Html(r#"
|
||||
fn general_not_found() -> content::RawHtml<&'static str> {
|
||||
content::RawHtml(r#"
|
||||
<p>Hmm... What are you looking for?</p>
|
||||
Say <a href="/hello/Sergio/100">hello!</a>
|
||||
"#)
|
||||
}
|
||||
|
||||
#[catch(404)]
|
||||
fn hello_not_found(req: &Request<'_>) -> content::Html<String> {
|
||||
content::Html(format!("\
|
||||
fn hello_not_found(req: &Request<'_>) -> content::RawHtml<String> {
|
||||
content::RawHtml(format!("\
|
||||
<p>Sorry, but '{}' is not a valid path!</p>\
|
||||
<p>Try visiting /hello/<name>/<age> instead.</p>",
|
||||
req.uri()))
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::io;
|
|||
|
||||
use rocket::data::{Data, ToByteUnit};
|
||||
use rocket::http::uri::Absolute;
|
||||
use rocket::response::content::Plain;
|
||||
use rocket::response::content::RawText;
|
||||
use rocket::tokio::fs::{self, File};
|
||||
|
||||
use crate::paste_id::PasteId;
|
||||
|
@ -24,8 +24,8 @@ async fn upload(paste: Data<'_>) -> io::Result<String> {
|
|||
}
|
||||
|
||||
#[get("/<id>")]
|
||||
async fn retrieve(id: PasteId<'_>) -> Option<Plain<File>> {
|
||||
File::open(id.file_path()).await.map(Plain).ok()
|
||||
async fn retrieve(id: PasteId<'_>) -> Option<RawText<File>> {
|
||||
File::open(id.file_path()).await.map(RawText).ok()
|
||||
}
|
||||
|
||||
#[delete("/<id>")]
|
||||
|
|
|
@ -89,26 +89,26 @@ fn maybe_redir(name: &str) -> Result<&'static str, Redirect> {
|
|||
use rocket::Request;
|
||||
use rocket::response::content;
|
||||
|
||||
// NOTE: This example explicitly uses the `Json` type from `response::content`
|
||||
// for demonstration purposes. In a real application, _always_ prefer to use
|
||||
// `rocket::serde::json::Json` instead!
|
||||
// NOTE: This example explicitly uses the `RawJson` type from
|
||||
// `response::content` for demonstration purposes. In a real application,
|
||||
// _always_ prefer to use `rocket::serde::json::Json` instead!
|
||||
|
||||
// In a `GET` request and all other non-payload supporting request types, the
|
||||
// preferred media type in the Accept header is matched against the `format` in
|
||||
// the route attribute. Because the client can use non-specific media types like
|
||||
// `*/*` in `Accept`, these first two routes would collide without `rank`.
|
||||
#[get("/content", format = "xml", rank = 1)]
|
||||
fn xml() -> content::Xml<&'static str> {
|
||||
content::Xml("<payload>I'm here</payload>")
|
||||
fn xml() -> content::RawXml<&'static str> {
|
||||
content::RawXml("<payload>I'm here</payload>")
|
||||
}
|
||||
|
||||
#[get("/content", format = "json", rank = 2)]
|
||||
fn json() -> content::Json<&'static str> {
|
||||
content::Json(r#"{ "payload": "I'm here" }"#)
|
||||
fn json() -> content::RawJson<&'static str> {
|
||||
content::RawJson(r#"{ "payload": "I'm here" }"#)
|
||||
}
|
||||
|
||||
#[catch(404)]
|
||||
fn not_found(request: &Request<'_>) -> content::Html<String> {
|
||||
fn not_found(request: &Request<'_>) -> content::RawHtml<String> {
|
||||
let html = match request.format() {
|
||||
Some(ref mt) if !(mt.is_xml() || mt.is_html()) => {
|
||||
format!("<p>'{}' requests are not supported.</p>", mt)
|
||||
|
@ -118,24 +118,24 @@ fn not_found(request: &Request<'_>) -> content::Html<String> {
|
|||
request.uri())
|
||||
};
|
||||
|
||||
content::Html(html)
|
||||
content::RawHtml(html)
|
||||
}
|
||||
|
||||
/******************************* `Either` Responder ***************************/
|
||||
|
||||
use rocket::Either;
|
||||
use rocket::response::content::{Json, MsgPack};
|
||||
use rocket::response::content::{RawJson, RawMsgPack};
|
||||
use rocket::http::uncased::AsUncased;
|
||||
|
||||
// NOTE: In a real application, we'd use `Json` and `MsgPack` from
|
||||
// `rocket::serde`, which perform automatic serialization of responses and
|
||||
// automatically set the `Content-Type`.
|
||||
#[get("/content/<kind>")]
|
||||
fn json_or_msgpack(kind: &str) -> Either<Json<&'static str>, MsgPack<&'static [u8]>> {
|
||||
fn json_or_msgpack(kind: &str) -> Either<RawJson<&'static str>, RawMsgPack<&'static [u8]>> {
|
||||
if kind.as_uncased() == "msgpack" {
|
||||
Either::Right(MsgPack(&[162, 104, 105]))
|
||||
Either::Right(RawMsgPack(&[162, 104, 105]))
|
||||
} else {
|
||||
Either::Left(Json("\"hi\""))
|
||||
Either::Left(RawJson("\"hi\""))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ fn json_or_msgpack(kind: &str) -> Either<Json<&'static str>, MsgPack<&'static [u
|
|||
|
||||
use std::borrow::Cow;
|
||||
|
||||
use rocket::response::content::Html;
|
||||
use rocket::response::content::RawHtml;
|
||||
|
||||
#[derive(Responder)]
|
||||
enum StoredData {
|
||||
|
@ -151,7 +151,7 @@ enum StoredData {
|
|||
String(Cow<'static, str>),
|
||||
Bytes(Vec<u8>),
|
||||
#[response(status = 401)]
|
||||
NotAuthorized(Html<&'static str>),
|
||||
NotAuthorized(RawHtml<&'static str>),
|
||||
}
|
||||
|
||||
#[derive(FromFormField, UriDisplayQuery)]
|
||||
|
@ -170,7 +170,7 @@ async fn custom(kind: Option<Kind>) -> StoredData {
|
|||
},
|
||||
Some(Kind::String) => StoredData::String("Hey, I'm some data.".into()),
|
||||
Some(Kind::Bytes) => StoredData::Bytes(vec![72, 105]),
|
||||
None => StoredData::NotAuthorized(Html("No no no!"))
|
||||
None => StoredData::NotAuthorized(RawHtml("No no no!"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use rocket::State;
|
||||
use rocket::response::content;
|
||||
use rocket::response::content::RawHtml;
|
||||
use rocket::fairing::AdHoc;
|
||||
|
||||
struct HitCount(AtomicUsize);
|
||||
|
||||
#[get("/")]
|
||||
fn index(hit_count: &State<HitCount>) -> content::Html<String> {
|
||||
fn index(hit_count: &State<HitCount>) -> RawHtml<String> {
|
||||
let count = hit_count.0.fetch_add(1, Ordering::Relaxed) + 1;
|
||||
content::Html(format!("Your visit is recorded!<br /><br />Visits: {}", count))
|
||||
RawHtml(format!("Your visit is recorded!<br /><br />Visits: {}", count))
|
||||
}
|
||||
|
||||
pub fn stage() -> AdHoc {
|
||||
|
|
|
@ -5,12 +5,12 @@ mod tera;
|
|||
|
||||
#[cfg(test)] mod tests;
|
||||
|
||||
use rocket::response::content::Html;
|
||||
use rocket::response::content::RawHtml;
|
||||
use rocket_dyn_templates::Template;
|
||||
|
||||
#[get("/")]
|
||||
fn index() -> Html<&'static str> {
|
||||
Html(r#"See <a href="tera">Tera</a> or <a href="hbs">Handlebars</a>."#)
|
||||
fn index() -> RawHtml<&'static str> {
|
||||
RawHtml(r#"See <a href="tera">Tera</a> or <a href="hbs">Handlebars</a>."#)
|
||||
}
|
||||
|
||||
#[launch]
|
||||
|
|
|
@ -50,7 +50,7 @@ fn new(id: usize) -> status::Accepted<String> {
|
|||
Similarly, the types in the [`content` module](@api/rocket/response/content/)
|
||||
can be used to override the Content-Type of a response. For instance, to set the
|
||||
Content-Type of `&'static str` to JSON, as well as setting the status code to an
|
||||
arbitrary one like `418 I'm a teapot`, combine [`content::Json`] with
|
||||
arbitrary one like `418 I'm a teapot`, combine [`content::RawJson`] with
|
||||
[`status::Custom`]:
|
||||
|
||||
```rust
|
||||
|
@ -59,16 +59,16 @@ use rocket::http::Status;
|
|||
use rocket::response::{content, status};
|
||||
|
||||
#[get("/")]
|
||||
fn json() -> status::Custom<content::Json<&'static str>> {
|
||||
status::Custom(Status::ImATeapot, content::Json("{ \"hi\": \"world\" }"))
|
||||
fn json() -> status::Custom<content::RawJson<&'static str>> {
|
||||
status::Custom(Status::ImATeapot, content::RawJson("{ \"hi\": \"world\" }"))
|
||||
}
|
||||
```
|
||||
|
||||
! warning: This is _not_ the same as [`serde::json::Json`]!
|
||||
|
||||
The built-in `(Status, R)` and `(ContentType, R)` responders, where `R:
|
||||
Responder`, are short-hands for the `status::Custom` and `content::Custom`
|
||||
responders:
|
||||
Responder`, also override the `Status` and `Content-Type` of responses,
|
||||
respectively:
|
||||
|
||||
```rust
|
||||
# #[macro_use] extern crate rocket;
|
||||
|
|
Loading…
Reference in New Issue