mirror of https://github.com/rwf2/Rocket.git
Initial cleanup of 'http' docs. Add 'handler::Outcome' docs.
This commit also changes the signature of the 'ContentType' 'from_extension" method so that it returns an 'Option<ContentType>' as opposed to 'ContentType'. This commit also disallows negative quality values in 'Accept' media types.
This commit is contained in:
parent
cdf9ff9bde
commit
6a7fde6d70
|
@ -197,10 +197,10 @@ impl RouteGenerateExt for RouteParams {
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
let $ident: $ty = match
|
let $ident: $ty = match
|
||||||
::rocket::request::FromRequest::from_request(__req) {
|
::rocket::request::FromRequest::from_request(__req) {
|
||||||
::rocket::outcome::Outcome::Success(v) => v,
|
::rocket::Outcome::Success(v) => v,
|
||||||
::rocket::outcome::Outcome::Forward(_) =>
|
::rocket::Outcome::Forward(_) =>
|
||||||
return ::rocket::Outcome::forward(__data),
|
return ::rocket::Outcome::Forward(__data),
|
||||||
::rocket::outcome::Outcome::Failure((code, _)) => {
|
::rocket::Outcome::Failure((code, _)) => {
|
||||||
return ::rocket::Outcome::Failure(code)
|
return ::rocket::Outcome::Failure(code)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,7 +34,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
let data_type = data_type_str.as_ref()
|
let data_type = data_type_str.as_ref()
|
||||||
.map(|ext| ContentType::from_extension(ext))
|
.and_then(|ext| ContentType::from_extension(ext))
|
||||||
.unwrap_or(ContentType::HTML);
|
.unwrap_or(ContentType::HTML);
|
||||||
|
|
||||||
templates.insert(name, TemplateInfo {
|
templates.insert(name, TemplateInfo {
|
||||||
|
|
|
@ -5,12 +5,7 @@ use super::data::BodyReader;
|
||||||
use http::hyper::net::NetworkStream;
|
use http::hyper::net::NetworkStream;
|
||||||
use http::hyper::h1::HttpReader;
|
use http::hyper::h1::HttpReader;
|
||||||
|
|
||||||
// It's very unfortunate that we have to wrap `BodyReader` in a `BufReader`
|
|
||||||
// since it already contains another `BufReader`. The issue is that Hyper's
|
|
||||||
// `HttpReader` doesn't implement `BufRead`. Unfortunately, this will likely
|
|
||||||
// stay "double buffered" until we switch HTTP libraries.
|
|
||||||
// |-- peek buf --|
|
// |-- peek buf --|
|
||||||
// pub type InnerStream = Chain<Cursor<Vec<u8>>, BufReader<BodyReader>>;
|
|
||||||
pub type InnerStream = Chain<Cursor<Vec<u8>>, BodyReader>;
|
pub type InnerStream = Chain<Cursor<Vec<u8>>, BodyReader>;
|
||||||
|
|
||||||
/// Raw data stream of a request body.
|
/// Raw data stream of a request body.
|
||||||
|
@ -18,9 +13,11 @@ pub type InnerStream = Chain<Cursor<Vec<u8>>, BodyReader>;
|
||||||
/// This stream can only be obtained by calling
|
/// This stream can only be obtained by calling
|
||||||
/// [Data::open](/rocket/data/struct.Data.html#method.open). The stream contains
|
/// [Data::open](/rocket/data/struct.Data.html#method.open). The stream contains
|
||||||
/// all of the data in the body of the request. It exposes no methods directly.
|
/// all of the data in the body of the request. It exposes no methods directly.
|
||||||
/// Instead, it must be used as an opaque `Read` or `BufRead` structure.
|
/// Instead, it must be used as an opaque `Read` structure.
|
||||||
pub struct DataStream(pub(crate) InnerStream);
|
pub struct DataStream(pub(crate) InnerStream);
|
||||||
|
|
||||||
|
// TODO: Have a `BufRead` impl for `DataStream`. At the moment, this isn't
|
||||||
|
// possible since Hyper's `HttpReader` doesn't implement `BufRead`.
|
||||||
impl Read for DataStream {
|
impl Read for DataStream {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
|
@ -29,18 +26,6 @@ impl Read for DataStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl BufRead for DataStream {
|
|
||||||
// #[inline(always)]
|
|
||||||
// fn fill_buf(&mut self) -> io::Result<&[u8]> {
|
|
||||||
// self.0.fill_buf()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[inline(always)]
|
|
||||||
// fn consume(&mut self, amt: usize) {
|
|
||||||
// self.0.consume(amt)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn kill_stream(stream: &mut BodyReader) {
|
pub fn kill_stream(stream: &mut BodyReader) {
|
||||||
// Only do the expensive reading if we're not sure we're done.
|
// Only do the expensive reading if we're not sure we're done.
|
||||||
use self::HttpReader::*;
|
use self::HttpReader::*;
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
//! fairings to rewrite or record information about requests and responses, or
|
//! fairings to rewrite or record information about requests and responses, or
|
||||||
//! to perform an action once a Rocket application has launched.
|
//! to perform an action once a Rocket application has launched.
|
||||||
//!
|
//!
|
||||||
|
//! To learn more about writing a fairing, see the [`Fairing` trait
|
||||||
|
//! documentation](/rocket/fairing/trait.Fairing.html).
|
||||||
|
//!
|
||||||
//! ## Attaching
|
//! ## Attaching
|
||||||
//!
|
//!
|
||||||
//! You must inform Rocket about fairings that you wish to be active by calling
|
//! You must inform Rocket about fairings that you wish to be active by calling
|
||||||
|
|
|
@ -11,6 +11,22 @@ use outcome;
|
||||||
pub type Outcome<'r> = outcome::Outcome<Response<'r>, Status, Data>;
|
pub type Outcome<'r> = outcome::Outcome<Response<'r>, Status, Data>;
|
||||||
|
|
||||||
impl<'r> Outcome<'r> {
|
impl<'r> Outcome<'r> {
|
||||||
|
/// Return the `Outcome` of response to `req` from `responder`.
|
||||||
|
///
|
||||||
|
/// If the responder responds with `Ok`, an outcome of `Success` is returns
|
||||||
|
/// with the response. If the outcomes reeturns `Err`, an outcome of
|
||||||
|
/// `Failure` is returned with the status code.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::{Request, Data};
|
||||||
|
/// use rocket::handler::Outcome;
|
||||||
|
///
|
||||||
|
/// fn str_responder(req: &Request, _: Data) -> Outcome<'static> {
|
||||||
|
/// Outcome::from(req, "Hello, world!")
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from<T: Responder<'r>>(req: &Request, responder: T) -> Outcome<'r> {
|
pub fn from<T: Responder<'r>>(req: &Request, responder: T) -> Outcome<'r> {
|
||||||
match responder.respond_to(req) {
|
match responder.respond_to(req) {
|
||||||
|
@ -19,11 +35,44 @@ impl<'r> Outcome<'r> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return an `Outcome` of `Failure` with the status code `code`. This is
|
||||||
|
/// equivalent to `Outcome::Failure(code)`.
|
||||||
|
///
|
||||||
|
/// This method exists to be used during manual routing where
|
||||||
|
/// `rocket::handler::Outcome` is imported instead of `rocket::Outcome`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::{Request, Data};
|
||||||
|
/// use rocket::handler::Outcome;
|
||||||
|
/// use rocket::http::Status;
|
||||||
|
///
|
||||||
|
/// fn bad_req_route(_: &Request, _: Data) -> Outcome<'static> {
|
||||||
|
/// Outcome::failure(Status::BadRequest)
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn failure(code: Status) -> Outcome<'static> {
|
pub fn failure(code: Status) -> Outcome<'static> {
|
||||||
outcome::Outcome::Failure(code)
|
outcome::Outcome::Failure(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return an `Outcome` of `Forward` with the data `data`. This is
|
||||||
|
/// equivalent to `Outcome::Forward(data)`.
|
||||||
|
///
|
||||||
|
/// This method exists to be used during manual routing where
|
||||||
|
/// `rocket::handler::Outcome` is imported instead of `rocket::Outcome`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::{Request, Data};
|
||||||
|
/// use rocket::handler::Outcome;
|
||||||
|
///
|
||||||
|
/// fn always_forward(_: &Request, data: Data) -> Outcome<'static> {
|
||||||
|
/// Outcome::forward(data)
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn forward(data: Data) -> Outcome<'static> {
|
pub fn forward(data: Data) -> Outcome<'static> {
|
||||||
outcome::Outcome::Forward(data)
|
outcome::Outcome::Forward(data)
|
||||||
|
|
|
@ -26,11 +26,6 @@ impl WeightedMediaType {
|
||||||
pub fn media_type(&self) -> &MediaType {
|
pub fn media_type(&self) -> &MediaType {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn into_media_type(self) -> MediaType {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MediaType> for WeightedMediaType {
|
impl From<MediaType> for WeightedMediaType {
|
||||||
|
|
|
@ -46,29 +46,13 @@ macro_rules! content_types {
|
||||||
($($name:ident ($check:ident): $str:expr, $t:expr,
|
($($name:ident ($check:ident): $str:expr, $t:expr,
|
||||||
$s:expr $(; $k:expr => $v:expr)*),+) => {
|
$s:expr $(; $k:expr => $v:expr)*),+) => {
|
||||||
$(
|
$(
|
||||||
#[doc="Media type for <b>"] #[doc=$str] #[doc="</b>: <i>"]
|
#[doc="Content-Type for <b>"] #[doc=$str] #[doc="</b>: <i>"]
|
||||||
#[doc=$t] #[doc="/"] #[doc=$s]
|
#[doc=$t] #[doc="/"] #[doc=$s]
|
||||||
$(#[doc="; "] #[doc=$k] #[doc=" = "] #[doc=$v])*
|
$(#[doc="; "] #[doc=$k] #[doc=" = "] #[doc=$v])*
|
||||||
#[doc="</i>"]
|
#[doc="</i>"]
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
pub const $name: ContentType = ContentType(MediaType::$name);
|
pub const $name: ContentType = ContentType(MediaType::$name);
|
||||||
|
|
||||||
#[doc="Returns `true` if `self` is the media type for <b>"]
|
|
||||||
#[doc=$str]
|
|
||||||
#[doc="</b>, "]
|
|
||||||
/// without considering parameters.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn $check(&self) -> bool {
|
|
||||||
*self == ContentType::$name
|
|
||||||
}
|
|
||||||
)+
|
)+
|
||||||
|
|
||||||
/// Returns `true` if this `ContentType` is known to Rocket, that is,
|
|
||||||
/// there is an associated constant for `self`.
|
|
||||||
pub fn is_known(&self) -> bool {
|
|
||||||
$(if self.$check() { return true })+
|
|
||||||
false
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,11 +79,12 @@ impl ContentType {
|
||||||
ContentType(MediaType::new(top, sub))
|
ContentType(MediaType::new(top, sub))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the Content-Type associated with the extension `ext`. Not all
|
/// Returns the Content-Type associated with the extension `ext` if the
|
||||||
/// extensions are recognized. If an extensions is not recognized, then this
|
/// extension is recognized. Not all extensions are recognized. If an
|
||||||
/// method returns a ContentType of `Any`. The currently recognized
|
/// extensions is not recognized, then this method returns `None`. The
|
||||||
/// extensions are: txt, html, htm, xml, js, css, json, png, gif, bmp, jpeg,
|
/// currently recognized extensions are txt, html, htm, xml, csv, js, css,
|
||||||
/// jpg, and pdf.
|
/// json, png, gif, bmp, jpeg, jpg, webp, svg, pdf, ttf, otf, woff, and
|
||||||
|
/// woff2.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
|
@ -109,7 +94,7 @@ impl ContentType {
|
||||||
/// use rocket::http::ContentType;
|
/// use rocket::http::ContentType;
|
||||||
///
|
///
|
||||||
/// let xml = ContentType::from_extension("xml");
|
/// let xml = ContentType::from_extension("xml");
|
||||||
/// assert!(xml.is_xml());
|
/// assert_eq!(xml, Some(ContentType::XML));
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// An unrecognized content type:
|
/// An unrecognized content type:
|
||||||
|
@ -118,12 +103,11 @@ impl ContentType {
|
||||||
/// use rocket::http::ContentType;
|
/// use rocket::http::ContentType;
|
||||||
///
|
///
|
||||||
/// let foo = ContentType::from_extension("foo");
|
/// let foo = ContentType::from_extension("foo");
|
||||||
/// assert!(foo.is_any());
|
/// assert!(foo.is_none());
|
||||||
/// ```
|
/// ```
|
||||||
pub fn from_extension(ext: &str) -> ContentType {
|
#[inline]
|
||||||
MediaType::from_extension(ext)
|
pub fn from_extension(ext: &str) -> Option<ContentType> {
|
||||||
.map(|mt| ContentType(mt))
|
MediaType::from_extension(ext).map(ContentType)
|
||||||
.unwrap_or(ContentType::Any)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new `ContentType` with top-level type `top`, subtype `sub`,
|
/// Creates a new `ContentType` with top-level type `top`, subtype `sub`,
|
||||||
|
@ -159,16 +143,21 @@ impl ContentType {
|
||||||
ContentType(MediaType::with_params(top, sub, ps))
|
ContentType(MediaType::with_params(top, sub, ps))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Borrows the inner `MediaType` of `self`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::http::{ContentType, MediaType};
|
||||||
|
///
|
||||||
|
/// let http = ContentType::HTML;
|
||||||
|
/// let media_type = http.media_type();
|
||||||
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn media_type(&self) -> &MediaType {
|
pub fn media_type(&self) -> &MediaType {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn into_media_type(self) -> MediaType {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
known_media_types!(content_types);
|
known_media_types!(content_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,30 +100,29 @@ macro_rules! media_types {
|
||||||
macro_rules! from_extension {
|
macro_rules! from_extension {
|
||||||
($($ext:expr => $name:ident),*) => (
|
($($ext:expr => $name:ident),*) => (
|
||||||
/// Returns the Media-Type associated with the extension `ext`. Not all
|
/// Returns the Media-Type associated with the extension `ext`. Not all
|
||||||
/// extensions are recognized. If an extensions is not recognized, then this
|
/// extensions are recognized. If an extensions is not recognized,
|
||||||
/// method returns a ContentType of `Any`. The currently recognized
|
/// `None` is returned. The currently recognized extensions are
|
||||||
/// extensions include
|
|
||||||
$(#[doc=$ext]#[doc=","])*
|
$(#[doc=$ext]#[doc=","])*
|
||||||
/// and is likely to grow.
|
/// and is likely to grow.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// A recognized content type:
|
/// A recognized media type:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use rocket::http::ContentType;
|
/// use rocket::http::MediaType;
|
||||||
///
|
///
|
||||||
/// let xml = ContentType::from_extension("xml");
|
/// let xml = MediaType::from_extension("xml");
|
||||||
/// assert!(xml.is_xml());
|
/// assert_eq!(xml, Some(MediaType::XML));
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// An unrecognized content type:
|
/// An unrecognized media type:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use rocket::http::ContentType;
|
/// use rocket::http::MediaType;
|
||||||
///
|
///
|
||||||
/// let foo = ContentType::from_extension("foo");
|
/// let foo = MediaType::from_extension("foo");
|
||||||
/// assert!(foo.is_any());
|
/// assert!(foo.is_none());
|
||||||
/// ```
|
/// ```
|
||||||
pub fn from_extension(ext: &str) -> Option<MediaType> {
|
pub fn from_extension(ext: &str) -> Option<MediaType> {
|
||||||
match ext {
|
match ext {
|
||||||
|
|
|
@ -9,6 +9,7 @@ fn q<'a>(_: &'a str, media_type: &MediaType) -> ParseResult<&'a str, Option<f32>
|
||||||
match media_type.params().next() {
|
match media_type.params().next() {
|
||||||
Some(("q", value)) if value.len() <= 5 => match value.parse::<f32>().ok() {
|
Some(("q", value)) if value.len() <= 5 => match value.parse::<f32>().ok() {
|
||||||
Some(q) if q > 1. => ParseError::custom("accept", "q value must be <= 1"),
|
Some(q) if q > 1. => ParseError::custom("accept", "q value must be <= 1"),
|
||||||
|
Some(q) if q < 0. => ParseError::custom("accept", "q value must be > 0"),
|
||||||
Some(q) => ParseResult::Done(Some(q)),
|
Some(q) => ParseResult::Done(Some(q)),
|
||||||
None => ParseError::custom("accept", "q value must be float")
|
None => ParseError::custom("accept", "q value must be float")
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,8 +14,8 @@ use std::fmt;
|
||||||
/// A reference to an uncased (case-preserving) ASCII string. This is typically
|
/// A reference to an uncased (case-preserving) ASCII string. This is typically
|
||||||
/// created from an `&str` as follows:
|
/// created from an `&str` as follows:
|
||||||
///
|
///
|
||||||
/// ```rust,ignore
|
/// ```rust
|
||||||
/// use rocket::http::ascii::UncasedStr;
|
/// use rocket::http::uncased::UncasedStr;
|
||||||
///
|
///
|
||||||
/// let ascii_ref: &UncasedStr = "Hello, world!".into();
|
/// let ascii_ref: &UncasedStr = "Hello, world!".into();
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -23,11 +23,34 @@ use std::fmt;
|
||||||
pub struct UncasedStr(str);
|
pub struct UncasedStr(str);
|
||||||
|
|
||||||
impl UncasedStr {
|
impl UncasedStr {
|
||||||
|
/// Returns a reference to an `UncasedStr` from an `&str`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::http::uncased::UncasedStr;
|
||||||
|
///
|
||||||
|
/// let uncased_str = UncasedStr::new("Hello!");
|
||||||
|
/// assert_eq!(uncased_str, "hello!");
|
||||||
|
/// assert_eq!(uncased_str, "Hello!");
|
||||||
|
/// assert_eq!(uncased_str, "HeLLo!");
|
||||||
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new(string: &str) -> &UncasedStr {
|
pub fn new(string: &str) -> &UncasedStr {
|
||||||
unsafe { &*(string as *const str as *const UncasedStr) }
|
unsafe { &*(string as *const str as *const UncasedStr) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `self` as an `&str`.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::http::uncased::UncasedStr;
|
||||||
|
///
|
||||||
|
/// let uncased_str = UncasedStr::new("Hello!");
|
||||||
|
/// assert_eq!(uncased_str.as_str(), "Hello!");
|
||||||
|
/// assert_ne!(uncased_str.as_str(), "hELLo!");
|
||||||
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn as_str(&self) -> &str {
|
pub fn as_str(&self) -> &str {
|
||||||
&self.0
|
&self.0
|
||||||
|
@ -109,39 +132,46 @@ impl fmt::Display for UncasedStr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An uncased (case-preserving) ASCII string.
|
/// An uncased (case-preserving), owned _or_ borrowed ASCII string.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Uncased<'s> {
|
pub struct Uncased<'s> {
|
||||||
|
#[doc(hidden)]
|
||||||
pub string: Cow<'s, str>
|
pub string: Cow<'s, str>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> Uncased<'s> {
|
impl<'s> Uncased<'s> {
|
||||||
/// Creates a new UncaseAscii string.
|
/// Creates a new `Uncased` string from `string` without allocating.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust,ignore
|
/// ```rust
|
||||||
/// use rocket::http::ascii::Uncased;
|
/// use rocket::http::uncased::Uncased;
|
||||||
///
|
///
|
||||||
/// let uncased_ascii = UncasedAScii::new("Content-Type");
|
/// let uncased = Uncased::new("Content-Type");
|
||||||
|
/// assert_eq!(uncased, "content-type");
|
||||||
|
/// assert_eq!(uncased, "CONTENT-Type");
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new<S: Into<Cow<'s, str>>>(string: S) -> Uncased<'s> {
|
pub fn new<S: Into<Cow<'s, str>>>(string: S) -> Uncased<'s> {
|
||||||
Uncased { string: string.into() }
|
Uncased { string: string.into() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts `self` into an owned `String`, allocating if necessary,
|
/// Converts `self` into an owned `String`, allocating if necessary.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::http::uncased::Uncased;
|
||||||
|
///
|
||||||
|
/// let uncased = Uncased::new("Content-Type");
|
||||||
|
/// let string = uncased.into_string();
|
||||||
|
/// assert_eq!(string, "Content-Type".to_string());
|
||||||
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn into_string(self) -> String {
|
pub fn into_string(self) -> String {
|
||||||
self.string.into_owned()
|
self.string.into_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Borrows the inner string.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn as_str(&self) -> &str {
|
|
||||||
self.string.borrow()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the inner `Cow`.
|
/// Returns the inner `Cow`.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -155,14 +185,14 @@ impl<'a> Deref for Uncased<'a> {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn deref(&self) -> &UncasedStr {
|
fn deref(&self) -> &UncasedStr {
|
||||||
self.as_str().into()
|
UncasedStr::new(self.string.borrow())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AsRef<UncasedStr> for Uncased<'a>{
|
impl<'a> AsRef<UncasedStr> for Uncased<'a>{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_ref(&self) -> &UncasedStr {
|
fn as_ref(&self) -> &UncasedStr {
|
||||||
self.as_str().into()
|
UncasedStr::new(self.string.borrow())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,9 +295,10 @@ impl<'s> Hash for Uncased<'s> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if `s1` and `s2` are equal without considering case. That is,
|
/// Returns true if `s1` and `s2` are equal without considering case.
|
||||||
/// for ASCII strings, this function returns s1.to_lower() == s2.to_lower(), but
|
///
|
||||||
/// does it in a much faster way.
|
/// That is, for ASCII strings, this function returns `s1.to_lower() ==
|
||||||
|
/// s2.to_lower()`, but does it in a much faster way.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn uncased_eq<S1: AsRef<str>, S2: AsRef<str>>(s1: S1, s2: S2) -> bool {
|
pub fn uncased_eq<S1: AsRef<str>, S2: AsRef<str>>(s1: S1, s2: S2) -> bool {
|
||||||
let ascii_ref_1: &UncasedStr = s1.as_ref().into();
|
let ascii_ref_1: &UncasedStr = s1.as_ref().into();
|
||||||
|
|
|
@ -85,8 +85,7 @@ impl Responder<'static> for NamedFile {
|
||||||
if let Some(ext) = self.path().extension() {
|
if let Some(ext) = self.path().extension() {
|
||||||
// TODO: Use Cow for lowercase.
|
// TODO: Use Cow for lowercase.
|
||||||
let ext_string = ext.to_string_lossy().to_lowercase();
|
let ext_string = ext.to_string_lossy().to_lowercase();
|
||||||
let content_type = ContentType::from_extension(&ext_string);
|
if let Some(content_type) = ContentType::from_extension(&ext_string) {
|
||||||
if !content_type.is_any() {
|
|
||||||
response.set_header(content_type);
|
response.set_header(content_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue