//! HTTP status codes //! //! This module contains HTTP-status code related structs an errors. The main //! type in this module is `StatusCode` which is not intended to be used through //! this module but rather the `http::StatusCode` type. //! //! # Examples //! //! ``` //! use http::StatusCode; //! //! assert_eq!(StatusCode::from_u16(200).unwrap(), StatusCode::OK); //! assert_eq!(StatusCode::NOT_FOUND, 404); //! assert!(StatusCode::OK.is_success()); //! ```
use std::convert::TryFrom; use std::num::NonZeroU16; use std::error::Error; use std::fmt; use std::str::FromStr;
/// An HTTP status code (`status-code` in RFC 7230 et al.). /// /// Constants are provided for known status codes, including those in the IANA /// [HTTP Status Code Registry]( /// https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml). /// /// Status code values in the range 100-999 (inclusive) are supported by this /// type. Values in the range 100-599 are semantically classified by the most /// significant digit. See [`StatusCode::is_success`], etc. Values above 599 /// are unclassified but allowed for legacy compatibility, though their use is /// discouraged. Applications may interpret such values as protocol errors. /// /// # Examples /// /// ``` /// use http::StatusCode; /// /// assert_eq!(StatusCode::from_u16(200).unwrap(), StatusCode::OK); /// assert_eq!(StatusCode::NOT_FOUND.as_u16(), 404); /// assert!(StatusCode::OK.is_success()); /// ``` #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pubstruct StatusCode(NonZeroU16);
/// A possible error value when converting a `StatusCode` from a `u16` or `&str` /// /// This error indicates that the supplied input was not a valid number, was less /// than 100, or was greater than 999. pubstruct InvalidStatusCode {
_priv: (),
}
impl StatusCode { /// Converts a u16 to a status code. /// /// The function validates the correctness of the supplied u16. It must be /// greater or equal to 100 and less than 1000. /// /// # Example /// /// ``` /// use http::StatusCode; /// /// let ok = StatusCode::from_u16(200).unwrap(); /// assert_eq!(ok, StatusCode::OK); /// /// let err = StatusCode::from_u16(99); /// assert!(err.is_err()); /// ``` #[inline] pubfn from_u16(src: u16) -> Result<StatusCode, InvalidStatusCode> { if src < 100 || src >= 1000 { return Err(InvalidStatusCode::new());
}
/// Converts a &[u8] to a status code pubfn from_bytes(src: &[u8]) -> Result<StatusCode, InvalidStatusCode> { if src.len() != 3 { return Err(InvalidStatusCode::new());
}
let a = src[0].wrapping_sub(b'0') as u16; let b = src[1].wrapping_sub(b'0') as u16; let c = src[2].wrapping_sub(b'0') as u16;
if a == 0 || a > 9 || b > 9 || c > 9 { return Err(InvalidStatusCode::new());
}
let status = (a * 100) + (b * 10) + c;
NonZeroU16::new(status)
.map(StatusCode)
.ok_or_else(InvalidStatusCode::new)
}
/// Returns the `u16` corresponding to this `StatusCode`. /// /// # Note /// /// This is the same as the `From<StatusCode>` implementation, but /// included as an inherent method because that implementation doesn't /// appear in rustdocs, as well as a way to force the type instead of /// relying on inference. /// /// # Example /// /// ``` /// let status = http::StatusCode::OK; /// assert_eq!(status.as_u16(), 200); /// ``` #[inline] pubfn as_u16(&self) -> u16 {
(*self).into()
}
/// Returns a &str representation of the `StatusCode` /// /// The return value only includes a numerical representation of the /// status code. The canonical reason is not included. /// /// # Example /// /// ``` /// let status = http::StatusCode::OK; /// assert_eq!(status.as_str(), "200"); /// ``` #[inline] pubfn as_str(&self) -> &str { let offset = (self.0.get() - 100) as usize; let offset = offset * 3;
// Invariant: self has checked range [100, 999] and CODE_DIGITS is // ASCII-only, of length 900 * 3 = 2700 bytes
/// Get the standardised `reason-phrase` for this status code. /// /// This is mostly here for servers writing responses, but could potentially have application /// at other times. /// /// The reason phrase is defined as being exclusively for human readers. You should avoid /// deriving any meaning from it at all costs. /// /// Bear in mind also that in HTTP/2.0 and HTTP/3.0 the reason phrase is abolished from /// transmission, and so this canonical reason phrase really is the only reason phrase you’ll /// find. /// /// # Example /// /// ``` /// let status = http::StatusCode::OK; /// assert_eq!(status.canonical_reason(), Some("OK")); /// ``` pubfn canonical_reason(&self) -> Option<&>'static str> {
canonical_reason(self.0.get())
}
/// Check if status is within 100-199. #[inline] pubfn is_informational(&self) -> bool { 200 > self.0.get() && self.0.get() >= 100
}
/// Check if status is within 200-299. #[inline] pubfn is_success(&self) -> bool { 300 > self.0.get() && self.0.get() >= 200
}
/// Check if status is within 300-399. #[inline] pubfn is_redirection(&self) -> bool { 400 > self.0.get() && self.0.get() >= 300
}
/// Check if status is within 400-499. #[inline] pubfn is_client_error(&self) -> bool { 500 > self.0.get() && self.0.get() >= 400
}
/// Check if status is within 500-599. #[inline] pubfn is_server_error(&self) -> bool { 600 > self.0.get() && self.0.get() >= 500
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.