mirror of https://github.com/rwf2/Rocket.git
Add 'const' constructor for 'MediaType'.
This commit is contained in:
parent
079e458b62
commit
5cf249581f
|
@ -70,8 +70,8 @@ impl FromMeta for ContentType {
|
|||
|
||||
impl ToTokens for ContentType {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
// Yeah, yeah. (((((i))).kn0w()))
|
||||
let media_type = MediaType((self.0).clone().0);
|
||||
let http_media_type = self.0.media_type().clone();
|
||||
let media_type = MediaType(http_media_type);
|
||||
tokens.extend(quote!(::rocket::http::ContentType(#media_type)));
|
||||
}
|
||||
}
|
||||
|
@ -94,27 +94,13 @@ impl FromMeta for MediaType {
|
|||
|
||||
impl ToTokens for MediaType {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
use std::iter::repeat;
|
||||
let (top, sub) = (self.0.top().as_str(), self.0.sub().as_str());
|
||||
let (keys, values) = self.0.params().split2();
|
||||
let http = quote!(::rocket::http);
|
||||
|
||||
let cow = quote!(::std::borrow::Cow);
|
||||
let (pub_http, http) = (quote!(::rocket::http), quote!(::rocket::http::private));
|
||||
let (http_, http__) = (repeat(&http), repeat(&http));
|
||||
let (cow_, cow__) = (repeat(&cow), repeat(&cow));
|
||||
|
||||
// TODO: Produce less code when possible (for known media types).
|
||||
tokens.extend(quote!(#pub_http::MediaType {
|
||||
source: #http::Source::None,
|
||||
top: #http::Indexed::Concrete(#cow::Borrowed(#top)),
|
||||
sub: #http::Indexed::Concrete(#cow::Borrowed(#sub)),
|
||||
params: #http::MediaParams::Static(&[
|
||||
#((
|
||||
#http_::Indexed::Concrete(#cow_::Borrowed(#keys)),
|
||||
#http__::Indexed::Concrete(#cow__::Borrowed(#values))
|
||||
)),*
|
||||
])
|
||||
}))
|
||||
tokens.extend(quote! {
|
||||
#http::MediaType::const_new(#top, #sub, &[#((#keys, #values)),*])
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ log = "0.4"
|
|||
ref-cast = "1.0"
|
||||
uncased = "0.9"
|
||||
parking_lot = "0.11"
|
||||
either = "1"
|
||||
|
||||
[dependencies.cookie]
|
||||
git = "https://github.com/SergioBenitez/cookie-rs.git"
|
||||
|
|
|
@ -3,120 +3,12 @@ use std::str::FromStr;
|
|||
use std::fmt;
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use either::Either;
|
||||
|
||||
use crate::{Header, MediaType};
|
||||
use crate::ext::IntoCollection;
|
||||
use crate::parse::parse_accept;
|
||||
|
||||
/// A `MediaType` with an associated quality value.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct QMediaType(pub MediaType, pub Option<f32>);
|
||||
|
||||
impl QMediaType {
|
||||
/// Retrieve the weight of the media type, if there is any.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate rocket;
|
||||
/// use rocket::http::{MediaType, QMediaType};
|
||||
///
|
||||
/// let q_type = QMediaType(MediaType::HTML, Some(0.3));
|
||||
/// assert_eq!(q_type.weight(), Some(0.3));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn weight(&self) -> Option<f32> {
|
||||
self.1
|
||||
}
|
||||
|
||||
/// Retrieve the weight of the media type or a given default value.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate rocket;
|
||||
/// use rocket::http::{MediaType, QMediaType};
|
||||
///
|
||||
/// let q_type = QMediaType(MediaType::HTML, Some(0.3));
|
||||
/// assert_eq!(q_type.weight_or(0.9), 0.3);
|
||||
///
|
||||
/// let q_type = QMediaType(MediaType::HTML, None);
|
||||
/// assert_eq!(q_type.weight_or(0.9), 0.9);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn weight_or(&self, default: f32) -> f32 {
|
||||
self.1.unwrap_or(default)
|
||||
}
|
||||
|
||||
/// Borrow the internal `MediaType`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate rocket;
|
||||
/// use rocket::http::{MediaType, QMediaType};
|
||||
///
|
||||
/// let q_type = QMediaType(MediaType::HTML, Some(0.3));
|
||||
/// assert_eq!(q_type.media_type(), &MediaType::HTML);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn media_type(&self) -> &MediaType {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MediaType> for QMediaType {
|
||||
#[inline(always)]
|
||||
fn from(media_type: MediaType) -> QMediaType {
|
||||
QMediaType(media_type, None)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for QMediaType {
|
||||
type Target = MediaType;
|
||||
|
||||
#[inline(always)]
|
||||
fn deref(&self) -> &MediaType {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: `Static` is needed for `const` items. Need `const SmallVec::new`.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum AcceptParams {
|
||||
Static(&'static [QMediaType]),
|
||||
Dynamic(SmallVec<[QMediaType; 1]>)
|
||||
}
|
||||
|
||||
impl Default for AcceptParams {
|
||||
fn default() -> Self {
|
||||
AcceptParams::Dynamic(SmallVec::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl Extend<QMediaType> for AcceptParams {
|
||||
fn extend<T: IntoIterator<Item = QMediaType>>(&mut self, iter: T) {
|
||||
match self {
|
||||
AcceptParams::Static(..) => panic!("can't add to static collection!"),
|
||||
AcceptParams::Dynamic(ref mut v) => v.extend(iter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for AcceptParams {
|
||||
fn eq(&self, other: &AcceptParams) -> bool {
|
||||
#[inline(always)]
|
||||
fn inner_types(params: &AcceptParams) -> &[QMediaType] {
|
||||
match *params {
|
||||
AcceptParams::Static(params) => params,
|
||||
AcceptParams::Dynamic(ref vec) => vec,
|
||||
}
|
||||
}
|
||||
|
||||
inner_types(self) == inner_types(other)
|
||||
}
|
||||
}
|
||||
|
||||
/// The HTTP Accept header.
|
||||
///
|
||||
/// An `Accept` header is composed of zero or more media types, each of which
|
||||
|
@ -160,9 +52,20 @@ impl PartialEq for AcceptParams {
|
|||
///
|
||||
/// let response = Response::build().header(Accept::JSON).finalize();
|
||||
/// ```
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Accept(pub(crate) AcceptParams);
|
||||
|
||||
/// A `MediaType` with an associated quality value.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct QMediaType(pub MediaType, pub Option<f32>);
|
||||
|
||||
// NOTE: `Static` is needed for `const` items. Need `const SmallVec::new`.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum AcceptParams {
|
||||
Static(QMediaType),
|
||||
Dynamic(SmallVec<[QMediaType; 1]>)
|
||||
}
|
||||
|
||||
macro_rules! accept_constructor {
|
||||
($($name:ident ($check:ident): $str:expr, $t:expr,
|
||||
$s:expr $(; $k:expr => $v:expr)*,)+) => {
|
||||
|
@ -173,19 +76,12 @@ macro_rules! accept_constructor {
|
|||
#[doc="</i>"]
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const $name: Accept = Accept(
|
||||
AcceptParams::Static(&[QMediaType(MediaType::$name, None)])
|
||||
AcceptParams::Static(QMediaType(MediaType::$name, None))
|
||||
);
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
||||
impl<T: IntoCollection<MediaType>> From<T> for Accept {
|
||||
#[inline(always)]
|
||||
fn from(items: T) -> Accept {
|
||||
Accept(AcceptParams::Dynamic(items.mapped(|item| item.into())))
|
||||
}
|
||||
}
|
||||
|
||||
impl Accept {
|
||||
/// Constructs a new `Accept` header from one or more media types.
|
||||
///
|
||||
|
@ -314,12 +210,10 @@ impl Accept {
|
|||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn iter<'a>(&'a self) -> impl Iterator<Item=&'a QMediaType> + 'a {
|
||||
let slice = match self.0 {
|
||||
AcceptParams::Static(slice) => slice,
|
||||
AcceptParams::Dynamic(ref vec) => &vec[..],
|
||||
};
|
||||
|
||||
slice.iter()
|
||||
match self.0 {
|
||||
AcceptParams::Static(ref val) => Either::Left(Some(val).into_iter()),
|
||||
AcceptParams::Dynamic(ref vec) => Either::Right(vec.iter())
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over all of the (bare) media types in `self`. Media
|
||||
|
@ -351,6 +245,19 @@ impl Accept {
|
|||
known_media_types!(accept_constructor);
|
||||
}
|
||||
|
||||
impl<T: IntoCollection<MediaType>> From<T> for Accept {
|
||||
#[inline(always)]
|
||||
fn from(items: T) -> Accept {
|
||||
Accept(AcceptParams::Dynamic(items.mapped(|item| item.into())))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Accept {
|
||||
fn eq(&self, other: &Accept) -> bool {
|
||||
self.iter().eq(other.iter())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Accept {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
for (i, media_type) in self.iter().enumerate() {
|
||||
|
@ -384,6 +291,90 @@ impl Into<Header<'static>> for Accept {
|
|||
}
|
||||
}
|
||||
|
||||
impl QMediaType {
|
||||
/// Retrieve the weight of the media type, if there is any.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate rocket;
|
||||
/// use rocket::http::{MediaType, QMediaType};
|
||||
///
|
||||
/// let q_type = QMediaType(MediaType::HTML, Some(0.3));
|
||||
/// assert_eq!(q_type.weight(), Some(0.3));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn weight(&self) -> Option<f32> {
|
||||
self.1
|
||||
}
|
||||
|
||||
/// Retrieve the weight of the media type or a given default value.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate rocket;
|
||||
/// use rocket::http::{MediaType, QMediaType};
|
||||
///
|
||||
/// let q_type = QMediaType(MediaType::HTML, Some(0.3));
|
||||
/// assert_eq!(q_type.weight_or(0.9), 0.3);
|
||||
///
|
||||
/// let q_type = QMediaType(MediaType::HTML, None);
|
||||
/// assert_eq!(q_type.weight_or(0.9), 0.9);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn weight_or(&self, default: f32) -> f32 {
|
||||
self.1.unwrap_or(default)
|
||||
}
|
||||
|
||||
/// Borrow the internal `MediaType`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # extern crate rocket;
|
||||
/// use rocket::http::{MediaType, QMediaType};
|
||||
///
|
||||
/// let q_type = QMediaType(MediaType::HTML, Some(0.3));
|
||||
/// assert_eq!(q_type.media_type(), &MediaType::HTML);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn media_type(&self) -> &MediaType {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MediaType> for QMediaType {
|
||||
#[inline(always)]
|
||||
fn from(media_type: MediaType) -> QMediaType {
|
||||
QMediaType(media_type, None)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for QMediaType {
|
||||
type Target = MediaType;
|
||||
|
||||
#[inline(always)]
|
||||
fn deref(&self) -> &MediaType {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for AcceptParams {
|
||||
fn default() -> Self {
|
||||
AcceptParams::Dynamic(SmallVec::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl Extend<QMediaType> for AcceptParams {
|
||||
fn extend<T: IntoIterator<Item = QMediaType>>(&mut self, iter: T) {
|
||||
match self {
|
||||
AcceptParams::Static(..) => panic!("can't add to static collection!"),
|
||||
AcceptParams::Dynamic(ref mut v) => v.extend(iter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{Accept, MediaType};
|
||||
|
|
|
@ -49,21 +49,17 @@ pub mod uncased {
|
|||
#[doc(inline)] pub use uncased::*;
|
||||
}
|
||||
|
||||
// Types that we expose for use by core.
|
||||
#[doc(hidden)]
|
||||
pub mod private {
|
||||
// We need to export these for codegen, but otherwise it's unnecessary.
|
||||
// TODO: Expose a `const fn` from ContentType when possible. (see RFC#1817)
|
||||
pub use crate::parse::Indexed;
|
||||
pub use crate::media_type::{MediaParams, Source};
|
||||
pub use smallvec::{SmallVec, Array};
|
||||
|
||||
// These we need to expose for core.
|
||||
pub mod cookie {
|
||||
pub use cookie::*;
|
||||
pub use crate::cookies::Key;
|
||||
}
|
||||
|
||||
// These as well.
|
||||
pub use crate::listener::{Incoming, Listener, Connection, bind_tcp};
|
||||
}
|
||||
|
||||
|
|
|
@ -3,72 +3,14 @@ use std::str::FromStr;
|
|||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use either::Either;
|
||||
|
||||
use crate::ext::IntoCollection;
|
||||
use crate::uncased::UncasedStr;
|
||||
use crate::parse::{Indexed, IndexedString, parse_media_type};
|
||||
|
||||
use smallvec::SmallVec;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct MediaParam {
|
||||
key: IndexedString,
|
||||
value: IndexedString,
|
||||
}
|
||||
|
||||
// FIXME: `Static` is needed for `const` items. Need `const SmallVec::new`.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MediaParams {
|
||||
Static(&'static [(IndexedString, IndexedString)]),
|
||||
Dynamic(SmallVec<[(IndexedString, IndexedString); 2]>)
|
||||
}
|
||||
|
||||
impl Default for MediaParams {
|
||||
fn default() -> Self {
|
||||
MediaParams::Dynamic(SmallVec::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl Extend<(IndexedString, IndexedString)> for MediaParams {
|
||||
fn extend<T: IntoIterator<Item = (IndexedString, IndexedString)>>(&mut self, iter: T) {
|
||||
match self {
|
||||
MediaParams::Static(..) => panic!("can't add to static collection!"),
|
||||
MediaParams::Dynamic(ref mut v) => v.extend(iter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for MediaParams {
|
||||
fn eq(&self, other: &MediaParams) -> bool {
|
||||
#[inline(always)]
|
||||
fn inner_types(params: &MediaParams) -> &[(IndexedString, IndexedString)] {
|
||||
match *params {
|
||||
MediaParams::Static(params) => params,
|
||||
MediaParams::Dynamic(ref vec) => vec,
|
||||
}
|
||||
}
|
||||
|
||||
inner_types(self) == inner_types(other)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Source {
|
||||
Known(&'static str),
|
||||
Custom(Cow<'static, str>),
|
||||
None
|
||||
}
|
||||
|
||||
impl Source {
|
||||
#[inline]
|
||||
fn as_str(&self) -> Option<&str> {
|
||||
match *self {
|
||||
Source::Known(s) => Some(s),
|
||||
Source::Custom(ref s) => Some(s.borrow()),
|
||||
Source::None => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An HTTP media type.
|
||||
///
|
||||
/// # Usage
|
||||
|
@ -110,21 +52,33 @@ impl Source {
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct MediaType {
|
||||
/// Storage for the entire media type string.
|
||||
#[doc(hidden)]
|
||||
pub source: Source,
|
||||
pub(crate) source: Source,
|
||||
/// The top-level type.
|
||||
#[doc(hidden)]
|
||||
pub top: IndexedString,
|
||||
pub(crate) top: IndexedString,
|
||||
/// The subtype.
|
||||
#[doc(hidden)]
|
||||
pub sub: IndexedString,
|
||||
pub(crate) sub: IndexedString,
|
||||
/// The parameters, if any.
|
||||
#[doc(hidden)]
|
||||
pub params: MediaParams
|
||||
pub(crate) params: MediaParams
|
||||
}
|
||||
|
||||
macro_rules! media_str {
|
||||
($string:expr) => (Indexed::Concrete(Cow::Borrowed($string)))
|
||||
#[derive(Debug, Clone)]
|
||||
struct MediaParam {
|
||||
key: IndexedString,
|
||||
value: IndexedString,
|
||||
}
|
||||
|
||||
// FIXME: `Static` is needed for `const` items. Need `const SmallVec::new`.
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) enum MediaParams {
|
||||
Static(&'static [(&'static str, &'static str)]),
|
||||
Dynamic(SmallVec<[(IndexedString, IndexedString); 2]>)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub(crate) enum Source {
|
||||
Known(&'static str),
|
||||
Custom(Cow<'static, str>),
|
||||
None
|
||||
}
|
||||
|
||||
macro_rules! media_types {
|
||||
|
@ -136,12 +90,10 @@ macro_rules! media_types {
|
|||
$(; @{$k}! @[=]! @{$v}!)* @{"`"}!.
|
||||
];
|
||||
#[allow(non_upper_case_globals)]
|
||||
pub const $name: MediaType = MediaType {
|
||||
source: Source::Known(concat!($t, "/", $s, $("; ", $k, "=", $v),*)),
|
||||
top: media_str!($t),
|
||||
sub: media_str!($s),
|
||||
params: MediaParams::Static(&[$((media_str!($k), media_str!($v))),*])
|
||||
};
|
||||
pub const $name: MediaType = MediaType::new_known(
|
||||
concat!($t, "/", $s, $("; ", $k, "=", $v),*),
|
||||
$t, $s, &[$(($k, $v)),*]
|
||||
);
|
||||
);
|
||||
)+
|
||||
|
||||
|
@ -357,6 +309,50 @@ impl MediaType {
|
|||
}
|
||||
}
|
||||
|
||||
/// A `const` variant of [`MediaType::with_params()`]. Creates a new
|
||||
/// `MediaType` with top-level type `top`, subtype `sub`, and parameters
|
||||
/// `params`, which may be empty.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// Create a custom `application/x-person` media type:
|
||||
///
|
||||
/// ```rust
|
||||
/// use rocket::http::MediaType;
|
||||
///
|
||||
/// let custom = MediaType::const_new("application", "x-person", &[]);
|
||||
/// assert_eq!(custom.top(), "application");
|
||||
/// assert_eq!(custom.sub(), "x-person");
|
||||
/// ```
|
||||
#[inline]
|
||||
pub const fn const_new(
|
||||
top: &'static str,
|
||||
sub: &'static str,
|
||||
params: &'static [(&'static str, &'static str)]
|
||||
) -> MediaType {
|
||||
MediaType {
|
||||
source: Source::None,
|
||||
top: Indexed::Concrete(Cow::Borrowed(top)),
|
||||
sub: Indexed::Concrete(Cow::Borrowed(sub)),
|
||||
params: MediaParams::Static(params),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) const fn new_known(
|
||||
source: &'static str,
|
||||
top: &'static str,
|
||||
sub: &'static str,
|
||||
params: &'static [(&'static str, &'static str)]
|
||||
) -> MediaType {
|
||||
MediaType {
|
||||
source: Source::Known(source),
|
||||
top: Indexed::Concrete(Cow::Borrowed(top)),
|
||||
sub: Indexed::Concrete(Cow::Borrowed(sub)),
|
||||
params: MediaParams::Static(params),
|
||||
}
|
||||
}
|
||||
|
||||
known_shorthands!(parse_flexible);
|
||||
|
||||
known_extensions!(from_extension);
|
||||
|
@ -501,16 +497,15 @@ impl MediaType {
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn params<'a>(&'a self) -> impl Iterator<Item=(&'a str, &'a str)> + 'a {
|
||||
let param_slice = match self.params {
|
||||
MediaParams::Static(slice) => slice,
|
||||
MediaParams::Dynamic(ref vec) => &vec[..],
|
||||
};
|
||||
|
||||
param_slice.iter()
|
||||
.map(move |&(ref key, ref val)| {
|
||||
let source_str = self.source.as_str();
|
||||
(key.from_source(source_str), val.from_source(source_str))
|
||||
})
|
||||
match self.params {
|
||||
MediaParams::Static(ref slice) => Either::Left(slice.iter().cloned()),
|
||||
MediaParams::Dynamic(ref vec) => {
|
||||
Either::Right(vec.iter().map(move |&(ref key, ref val)| {
|
||||
let source_str = self.source.as_str();
|
||||
(key.from_source(source_str), val.from_source(source_str))
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
known_media_types!(media_types);
|
||||
|
@ -561,3 +556,29 @@ impl fmt::Display for MediaType {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for MediaParams {
|
||||
fn default() -> Self {
|
||||
MediaParams::Dynamic(SmallVec::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl Extend<(IndexedString, IndexedString)> for MediaParams {
|
||||
fn extend<T: IntoIterator<Item = (IndexedString, IndexedString)>>(&mut self, iter: T) {
|
||||
match self {
|
||||
MediaParams::Static(..) => panic!("can't add to static collection!"),
|
||||
MediaParams::Dynamic(ref mut v) => v.extend(iter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Source {
|
||||
#[inline]
|
||||
fn as_str(&self) -> Option<&str> {
|
||||
match *self {
|
||||
Source::Known(s) => Some(s),
|
||||
Source::Custom(ref s) => Some(s.borrow()),
|
||||
Source::None => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,5 +8,4 @@ pub use self::accept::*;
|
|||
|
||||
pub mod uri;
|
||||
|
||||
// Exposed for codegen.
|
||||
#[doc(hidden)] pub use self::indexed::*;
|
||||
pub use self::indexed::*;
|
||||
|
|
Loading…
Reference in New Issue