mirror of https://github.com/rwf2/Rocket.git
Remove unused reason phrase in 'Status'.
Closes #534. Co-authored-by: YetAnotherMinion <yam@thinkalexandria.com>
This commit is contained in:
parent
336a03e27f
commit
ad8d80907b
|
@ -26,14 +26,14 @@ impl FromMeta for Status {
|
||||||
return Err(meta.value_span().error("status must be in range [100, 599]"));
|
return Err(meta.value_span().error("status must be in range [100, 599]"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Status(http::Status::raw(num as u16)))
|
Ok(Status(http::Status::new(num as u16)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToTokens for Status {
|
impl ToTokens for Status {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
let (code, reason) = (self.0.code, self.0.reason);
|
let code = self.0.code;
|
||||||
tokens.extend(quote!(rocket::http::Status { code: #code, reason: #reason }));
|
tokens.extend(quote!(rocket::http::Status { code: #code }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -303,7 +303,7 @@ route_attribute!(options => Method::Options);
|
||||||
///
|
///
|
||||||
/// #[catch(default)]
|
/// #[catch(default)]
|
||||||
/// fn default(status: Status, req: &Request) -> String {
|
/// fn default(status: Status, req: &Request) -> String {
|
||||||
/// format!("{} - {} ({})", status.code, status.reason, req.uri())
|
/// format!("{} ({})", status, req.uri())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
|
|
@ -53,7 +53,7 @@ async fn responder_foo() {
|
||||||
.respond_to(req)
|
.respond_to(req)
|
||||||
.expect("response okay");
|
.expect("response okay");
|
||||||
|
|
||||||
assert_eq!(r.status(), Status::raw(105));
|
assert_eq!(r.status().code, 105);
|
||||||
assert_eq!(r.content_type(), Some(ContentType::JSON));
|
assert_eq!(r.content_type(), Some(ContentType::JSON));
|
||||||
assert_eq!(r.body_mut().to_string().await.unwrap(), "goodbye");
|
assert_eq!(r.body_mut().to_string().await.unwrap(), "goodbye");
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,20 +42,43 @@ impl StatusClass {
|
||||||
class_check_fn!(is_unknown, "`Unknown`.", Unknown);
|
class_check_fn!(is_unknown, "`Unknown`.", Unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Structure representing an HTTP status: an integer code and a reason phrase.
|
/// Structure representing an HTTP status: an integer code.
|
||||||
///
|
///
|
||||||
/// # Usage
|
/// A `Status` should rarely be created directly. Instead, an associated
|
||||||
|
/// constant should be used; one is declared for every status defined in the
|
||||||
|
/// HTTP standard. If a custom status code _must_ be created, note that it is
|
||||||
|
/// not possible to set a custom reason phrase.
|
||||||
///
|
///
|
||||||
/// Status classes should rarely be created directly. Instead, an associated
|
/// ```rust
|
||||||
/// constant should be used; one is declared for every status defined
|
/// # extern crate rocket;
|
||||||
/// in the HTTP standard.
|
/// use rocket::http::Status;
|
||||||
|
///
|
||||||
|
/// // Create a status from a known constant.
|
||||||
|
/// let ok = Status::Ok;
|
||||||
|
/// assert_eq!(ok.code, 200);
|
||||||
|
/// assert_eq!(ok.reason(), Some("OK"));
|
||||||
|
///
|
||||||
|
/// let not_found = Status::NotFound;
|
||||||
|
/// assert_eq!(not_found.code, 404);
|
||||||
|
/// assert_eq!(not_found.reason(), Some("Not Found"));
|
||||||
|
///
|
||||||
|
/// // Or from a status code: `reason()` returns the phrase when known.
|
||||||
|
/// let gone = Status::new(410);
|
||||||
|
/// assert_eq!(gone.code, 410);
|
||||||
|
/// assert_eq!(gone.reason(), Some("Gone"));
|
||||||
|
///
|
||||||
|
/// // `reason()` returns `None` when unknown.
|
||||||
|
/// let custom = Status::new(599);
|
||||||
|
/// assert_eq!(custom.code, 599);
|
||||||
|
/// assert_eq!(custom.reason(), None);
|
||||||
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Responding
|
/// # Responding
|
||||||
///
|
///
|
||||||
/// To set a custom `Status` on a response, use a [`response::status`]
|
/// To set a custom `Status` on a response, use a [`response::status`]
|
||||||
/// responder. Alternatively, respond with `(Status, T)` where `T: Responder`, but
|
/// responder, which enforces correct status-based responses. Alternatively,
|
||||||
/// note that the response may require additional headers to be valid as
|
/// respond with `(Status, T)` where `T: Responder`, but beware that the
|
||||||
/// enforced by the types in [`response::status`].
|
/// response may be invalid if it requires additional headers.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # extern crate rocket;
|
/// # extern crate rocket;
|
||||||
|
@ -69,47 +92,10 @@ impl StatusClass {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`response::status`]: ../response/status/index.html
|
/// [`response::status`]: ../response/status/index.html
|
||||||
///
|
|
||||||
/// ## Example
|
|
||||||
///
|
|
||||||
/// A status of `200 OK` can be instantiated via the `Ok` constant:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # extern crate rocket;
|
|
||||||
/// use rocket::http::Status;
|
|
||||||
///
|
|
||||||
/// # #[allow(unused_variables)]
|
|
||||||
/// let ok = Status::Ok;
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// A status of `404 Not Found` can be instantiated via the `NotFound` constant:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # extern crate rocket;
|
|
||||||
/// use rocket::http::Status;
|
|
||||||
///
|
|
||||||
/// # #[allow(unused_variables)]
|
|
||||||
/// let not_found = Status::NotFound;
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// The code and phrase can be retrieved directly:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # extern crate rocket;
|
|
||||||
/// use rocket::http::Status;
|
|
||||||
///
|
|
||||||
/// let not_found = Status::NotFound;
|
|
||||||
///
|
|
||||||
/// assert_eq!(not_found.code, 404);
|
|
||||||
/// assert_eq!(not_found.reason, "Not Found");
|
|
||||||
/// assert_eq!(not_found.to_string(), "404 Not Found".to_string());
|
|
||||||
/// ```
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Status {
|
pub struct Status {
|
||||||
/// The HTTP status code associated with this status.
|
/// The HTTP status code associated with this status.
|
||||||
pub code: u16,
|
pub code: u16,
|
||||||
/// The HTTP reason phrase associated with this status.
|
|
||||||
pub reason: &'static str
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Status {
|
impl Default for Status {
|
||||||
|
@ -123,12 +109,66 @@ macro_rules! ctrs {
|
||||||
$(
|
$(
|
||||||
#[doc="[`Status`] with code <b>"]
|
#[doc="[`Status`] with code <b>"]
|
||||||
#[doc=$code_str]
|
#[doc=$code_str]
|
||||||
#[doc="</b> and reason <i>"]
|
#[doc="</b>."]
|
||||||
#[doc=$reason]
|
|
||||||
#[doc="</i>."]
|
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
pub const $name: Status = Status { code: $code, reason: $reason };
|
pub const $name: Status = Status { code: $code };
|
||||||
)+
|
)+
|
||||||
|
|
||||||
|
/// Creates a new `Status` with `code`. This should be used _only_ to
|
||||||
|
/// construct non-standard HTTP statuses. Use an associated constant for
|
||||||
|
/// standard statuses.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// Create a custom `299` status:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # extern crate rocket;
|
||||||
|
/// use rocket::http::Status;
|
||||||
|
///
|
||||||
|
/// let custom = Status::new(299);
|
||||||
|
/// assert_eq!(custom.code, 299);
|
||||||
|
/// ```
|
||||||
|
pub const fn new(code: u16) -> Status {
|
||||||
|
Status { code }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the class of a given status.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # extern crate rocket;
|
||||||
|
/// use rocket::http::{Status, StatusClass};
|
||||||
|
///
|
||||||
|
/// let processing = Status::Processing;
|
||||||
|
/// assert_eq!(processing.class(), StatusClass::Informational);
|
||||||
|
///
|
||||||
|
/// let ok = Status::Ok;
|
||||||
|
/// assert_eq!(ok.class(), StatusClass::Success);
|
||||||
|
///
|
||||||
|
/// let see_other = Status::SeeOther;
|
||||||
|
/// assert_eq!(see_other.class(), StatusClass::Redirection);
|
||||||
|
///
|
||||||
|
/// let not_found = Status::NotFound;
|
||||||
|
/// assert_eq!(not_found.class(), StatusClass::ClientError);
|
||||||
|
///
|
||||||
|
/// let internal_error = Status::InternalServerError;
|
||||||
|
/// assert_eq!(internal_error.class(), StatusClass::ServerError);
|
||||||
|
///
|
||||||
|
/// let custom = Status::new(600);
|
||||||
|
/// assert_eq!(custom.class(), StatusClass::Unknown);
|
||||||
|
/// ```
|
||||||
|
pub const fn class(self) -> StatusClass {
|
||||||
|
match self.code / 100 {
|
||||||
|
1 => StatusClass::Informational,
|
||||||
|
2 => StatusClass::Success,
|
||||||
|
3 => StatusClass::Redirection,
|
||||||
|
4 => StatusClass::ClientError,
|
||||||
|
5 => StatusClass::ServerError,
|
||||||
|
_ => StatusClass::Unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a Status given a standard status code `code`. If `code` is
|
/// Returns a Status given a standard status code `code`. If `code` is
|
||||||
/// not a known status code, `None` is returned.
|
/// not a known status code, `None` is returned.
|
||||||
|
@ -151,88 +191,78 @@ macro_rules! ctrs {
|
||||||
/// # extern crate rocket;
|
/// # extern crate rocket;
|
||||||
/// use rocket::http::Status;
|
/// use rocket::http::Status;
|
||||||
///
|
///
|
||||||
/// let not_found = Status::from_code(600);
|
/// let unknown = Status::from_code(600);
|
||||||
/// assert!(not_found.is_none());
|
/// assert!(unknown.is_none());
|
||||||
/// ```
|
/// ```
|
||||||
pub fn from_code(code: u16) -> Option<Status> {
|
pub const fn from_code(code: u16) -> Option<Status> {
|
||||||
match code {
|
match code {
|
||||||
$($code => Some(Status::$name),)+
|
$($code => Some(Status::$name),)+
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the canonical reason phrase if `self` corresponds to a
|
||||||
|
/// canonical, known status code. Otherwise, returns `None`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// Reason phrase from a known `code`:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # extern crate rocket;
|
||||||
|
/// use rocket::http::Status;
|
||||||
|
///
|
||||||
|
/// assert_eq!(Status::Created.reason(), Some("Created"));
|
||||||
|
/// assert_eq!(Status::new(200).reason(), Some("OK"));
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Absent phrase from an unknown `code`:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # extern crate rocket;
|
||||||
|
/// use rocket::http::Status;
|
||||||
|
///
|
||||||
|
/// assert_eq!(Status::new(499).reason(), None);
|
||||||
|
/// ```
|
||||||
|
pub const fn reason(&self) -> Option<&'static str> {
|
||||||
|
match self.code {
|
||||||
|
$($code => Some($reason),)+
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the canonical reason phrase if `self` corresponds to a
|
||||||
|
/// canonical, known status code, or an unspecified but relevant reason
|
||||||
|
/// phrase otherwise.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # extern crate rocket;
|
||||||
|
/// use rocket::http::Status;
|
||||||
|
///
|
||||||
|
/// assert_eq!(Status::NotFound.reason_lossy(), "Not Found");
|
||||||
|
/// assert_eq!(Status::new(100).reason_lossy(), "Continue");
|
||||||
|
/// assert!(!Status::new(699).reason_lossy().is_empty());
|
||||||
|
/// ```
|
||||||
|
pub const fn reason_lossy(&self) -> &'static str {
|
||||||
|
if let Some(lossless) = self.reason() {
|
||||||
|
return lossless;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.class() {
|
||||||
|
StatusClass::Informational => "Informational",
|
||||||
|
StatusClass::Success => "Success",
|
||||||
|
StatusClass::Redirection => "Redirection",
|
||||||
|
StatusClass::ClientError => "Client Error",
|
||||||
|
StatusClass::ServerError => "Server Error",
|
||||||
|
StatusClass::Unknown => "Unknown"
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Status {
|
impl Status {
|
||||||
/// Creates a new `Status` with `code` and `reason`. This should be used _only_
|
|
||||||
/// to construct non-standard HTTP statuses. Use an associated constant for
|
|
||||||
/// standard statuses.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// Create a custom `299 Somewhat Successful` status:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # extern crate rocket;
|
|
||||||
/// use rocket::http::Status;
|
|
||||||
///
|
|
||||||
/// let custom = Status::new(299, "Somewhat Successful");
|
|
||||||
/// assert_eq!(custom.to_string(), "299 Somewhat Successful".to_string());
|
|
||||||
/// ```
|
|
||||||
#[inline(always)]
|
|
||||||
pub const fn new(code: u16, reason: &'static str) -> Status {
|
|
||||||
Status { code, reason }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the class of a given status.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # extern crate rocket;
|
|
||||||
/// use rocket::http::{Status, StatusClass};
|
|
||||||
///
|
|
||||||
/// let processing = Status::Processing;
|
|
||||||
/// assert_eq!(processing.class(), StatusClass::Informational);
|
|
||||||
///
|
|
||||||
/// let ok = Status::Ok;
|
|
||||||
/// assert_eq!(ok.class(), StatusClass::Success);
|
|
||||||
///
|
|
||||||
/// let see_other = Status::SeeOther;
|
|
||||||
/// assert_eq!(see_other.class(), StatusClass::Redirection);
|
|
||||||
///
|
|
||||||
/// let not_found = Status::NotFound;
|
|
||||||
/// assert_eq!(not_found.class(), StatusClass::ClientError);
|
|
||||||
///
|
|
||||||
/// let internal_error = Status::InternalServerError;
|
|
||||||
/// assert_eq!(internal_error.class(), StatusClass::ServerError);
|
|
||||||
///
|
|
||||||
/// let custom = Status::new(600, "Bizarre");
|
|
||||||
/// assert_eq!(custom.class(), StatusClass::Unknown);
|
|
||||||
/// ```
|
|
||||||
pub fn class(self) -> StatusClass {
|
|
||||||
match self.code / 100 {
|
|
||||||
1 => StatusClass::Informational,
|
|
||||||
2 => StatusClass::Success,
|
|
||||||
3 => StatusClass::Redirection,
|
|
||||||
4 => StatusClass::ClientError,
|
|
||||||
5 => StatusClass::ServerError,
|
|
||||||
_ => StatusClass::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a status from a given status code. If the status code is a
|
|
||||||
/// standard code, then the reason phrase is populated accordingly.
|
|
||||||
/// Otherwise the reason phrase is set to "<unknown code>".
|
|
||||||
#[inline]
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn raw(code: u16) -> Status {
|
|
||||||
match Status::from_code(code) {
|
|
||||||
Some(status) => status,
|
|
||||||
None => Status::new(code, "<unknown code>")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ctrs! {
|
ctrs! {
|
||||||
100, "100", Continue => "Continue",
|
100, "100", Continue => "Continue",
|
||||||
101, "101", SwitchingProtocols => "Switching Protocols",
|
101, "101", SwitchingProtocols => "Switching Protocols",
|
||||||
|
@ -300,7 +330,7 @@ impl Status {
|
||||||
impl fmt::Display for Status {
|
impl fmt::Display for Status {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "{} {}", self.code, self.reason)
|
write!(f, "{} {}", self.code, self.reason_lossy())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,27 +106,6 @@ impl<'r> Builder<'r> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the status of the `Response` being built to a custom status
|
|
||||||
/// constructed from the `code` and `reason` phrase.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// use rocket::Response;
|
|
||||||
/// use rocket::http::Status;
|
|
||||||
///
|
|
||||||
/// let response = Response::build()
|
|
||||||
/// .raw_status(699, "Alien Encounter")
|
|
||||||
/// .finalize();
|
|
||||||
///
|
|
||||||
/// assert_eq!(response.status(), Status::new(699, "Alien Encounter"));
|
|
||||||
/// ```
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn raw_status(&mut self, code: u16, reason: &'static str) -> &mut Builder<'r> {
|
|
||||||
self.response.set_raw_status(code, reason);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds `header` to the `Response`, replacing any header with the same name
|
/// Adds `header` to the `Response`, replacing any header with the same name
|
||||||
/// that already exists in the response. If multiple headers with
|
/// that already exists in the response. If multiple headers with
|
||||||
/// the same name exist, they are all removed, and only the new header and
|
/// the same name exist, they are all removed, and only the new header and
|
||||||
|
@ -544,25 +523,6 @@ impl<'r> Response<'r> {
|
||||||
self.headers().get_one("Content-Type").and_then(|v| v.parse().ok())
|
self.headers().get_one("Content-Type").and_then(|v| v.parse().ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the status of `self` to a custom `status` with status code `code`
|
|
||||||
/// and reason phrase `reason`. This method should be used sparingly; prefer
|
|
||||||
/// to use [set_status](#method.set_status) instead.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// use rocket::Response;
|
|
||||||
/// use rocket::http::Status;
|
|
||||||
///
|
|
||||||
/// let mut response = Response::new();
|
|
||||||
/// response.set_raw_status(699, "Tripped a Wire");
|
|
||||||
/// assert_eq!(response.status(), Status::new(699, "Tripped a Wire"));
|
|
||||||
/// ```
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn set_raw_status(&mut self, code: u16, reason: &'static str) {
|
|
||||||
self.status = Some(Status::new(code, reason));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an iterator over the cookies in `self` as identified by the
|
/// Returns an iterator over the cookies in `self` as identified by the
|
||||||
/// `Set-Cookie` header. Malformed cookies are skipped.
|
/// `Set-Cookie` header. Malformed cookies are skipped.
|
||||||
///
|
///
|
||||||
|
|
|
@ -13,7 +13,7 @@ fn hello(name: &str, age: i8) -> String {
|
||||||
|
|
||||||
#[get("/<code>")]
|
#[get("/<code>")]
|
||||||
fn forced_error(code: u16) -> Status {
|
fn forced_error(code: u16) -> Status {
|
||||||
Status::raw(code)
|
Status::new(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[catch(404)]
|
#[catch(404)]
|
||||||
|
@ -39,7 +39,7 @@ fn sergio_error() -> &'static str {
|
||||||
|
|
||||||
#[catch(default)]
|
#[catch(default)]
|
||||||
fn default_catcher(status: Status, req: &Request<'_>) -> status::Custom<String> {
|
fn default_catcher(status: Status, req: &Request<'_>) -> status::Custom<String> {
|
||||||
let msg = format!("{} - {} ({})", status.code, status.reason, req.uri());
|
let msg = format!("{} ({})", status, req.uri());
|
||||||
status::Custom(status, msg)
|
status::Custom(status, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,9 @@ fn forced_error() {
|
||||||
assert_eq!(response.into_string().unwrap(), expected.1);
|
assert_eq!(response.into_string().unwrap(), expected.1);
|
||||||
|
|
||||||
let request = client.get("/533");
|
let request = client.get("/533");
|
||||||
let expected = super::default_catcher(Status::raw(533), request.inner());
|
let expected = super::default_catcher(Status::new(533), request.inner());
|
||||||
let response = request.dispatch();
|
let response = request.dispatch();
|
||||||
assert_eq!(response.status(), Status::raw(533));
|
assert_eq!(response.status(), Status::new(533));
|
||||||
assert_eq!(response.into_string().unwrap(), expected.1);
|
assert_eq!(response.into_string().unwrap(), expected.1);
|
||||||
|
|
||||||
let request = client.get("/700");
|
let request = client.get("/700");
|
||||||
|
|
Loading…
Reference in New Issue