mirror of https://github.com/rwf2/Rocket.git
New type: ContentType. Parse ContentType from attribute.
This commit is contained in:
parent
c8eef33820
commit
bd9d553050
|
@ -13,4 +13,5 @@ members = [
|
||||||
"examples/redirect",
|
"examples/redirect",
|
||||||
"examples/static_files",
|
"examples/static_files",
|
||||||
"examples/todo",
|
"examples/todo",
|
||||||
|
"examples/content_types",
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,6 +7,7 @@ authors = ["Sergio Benitez <sb@sergio.bz>"]
|
||||||
term-painter = "*"
|
term-painter = "*"
|
||||||
hyper = "*"
|
hyper = "*"
|
||||||
url = "*"
|
url = "*"
|
||||||
|
mime = "*"
|
||||||
|
|
||||||
# [dependencies.hyper]
|
# [dependencies.hyper]
|
||||||
# git = "https://github.com/hyperium/hyper.git"
|
# git = "https://github.com/hyperium/hyper.git"
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
use method::Method;
|
use ::{Method, Handler};
|
||||||
use handler::Handler;
|
use content_type::ContentType;
|
||||||
|
|
||||||
pub struct StaticRouteInfo {
|
pub struct StaticRouteInfo {
|
||||||
pub method: Method,
|
pub method: Method,
|
||||||
pub path: &'static str,
|
pub path: &'static str,
|
||||||
pub handler: Handler
|
pub content_type: ContentType,
|
||||||
|
pub handler: Handler,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StaticCatchInfo {
|
pub struct StaticCatchInfo {
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
pub use mime::{Mime, TopLevel, SubLevel};
|
||||||
|
|
||||||
|
use std::str::FromStr;
|
||||||
|
use mime::{Param};
|
||||||
|
use self::TopLevel::{Text, Application};
|
||||||
|
use self::SubLevel::{Json, Html};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct ContentType(pub TopLevel, pub SubLevel, pub Option<Vec<Param>>);
|
||||||
|
|
||||||
|
impl ContentType {
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn of(t: TopLevel, s: SubLevel) -> ContentType {
|
||||||
|
ContentType(t, s, None)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn any() -> ContentType {
|
||||||
|
ContentType::of(TopLevel::Star, SubLevel::Star)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_json(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
ContentType(Application, Json, _) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_any(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
ContentType(TopLevel::Star, SubLevel::Star, None) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_ext(&self) -> bool {
|
||||||
|
if let TopLevel::Ext(_) = self.0 {
|
||||||
|
true
|
||||||
|
} else if let SubLevel::Ext(_) = self.1 {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_html(&self) -> bool {
|
||||||
|
match *self {
|
||||||
|
ContentType(Text, Html, _) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Mime> for ContentType {
|
||||||
|
fn into(self) -> Mime {
|
||||||
|
Mime(self.0, self.1, self.2.unwrap_or_default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Mime> for ContentType {
|
||||||
|
fn from(mime: Mime) -> ContentType {
|
||||||
|
let params = match mime.2.len() {
|
||||||
|
0 => None,
|
||||||
|
_ => Some(mime.2)
|
||||||
|
};
|
||||||
|
|
||||||
|
ContentType(mime.0, mime.1, params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for ContentType {
|
||||||
|
type Err = ();
|
||||||
|
|
||||||
|
fn from_str(raw: &str) -> Result<ContentType, ()> {
|
||||||
|
let mime = Mime::from_str(raw)?;
|
||||||
|
Ok(ContentType::from(mime))
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
extern crate term_painter;
|
extern crate term_painter;
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
extern crate mime;
|
||||||
|
|
||||||
mod method;
|
mod method;
|
||||||
mod error;
|
mod error;
|
||||||
|
@ -16,6 +17,7 @@ mod catcher;
|
||||||
pub mod form;
|
pub mod form;
|
||||||
pub mod request;
|
pub mod request;
|
||||||
pub mod response;
|
pub mod response;
|
||||||
|
pub mod content_type;
|
||||||
|
|
||||||
pub mod handler {
|
pub mod handler {
|
||||||
use super::{Request, Response};
|
use super::{Request, Response};
|
||||||
|
@ -23,6 +25,7 @@ pub mod handler {
|
||||||
pub type Handler = for<'r> fn(Request<'r>) -> Response<'r>;
|
pub type Handler = for<'r> fn(Request<'r>) -> Response<'r>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub use content_type::ContentType;
|
||||||
pub use codegen::{StaticRouteInfo, StaticCatchInfo};
|
pub use codegen::{StaticRouteInfo, StaticCatchInfo};
|
||||||
pub use request::Request;
|
pub use request::Request;
|
||||||
pub use method::Method;
|
pub use method::Method;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
use ::{Method, Handler, StaticRouteInfo};
|
||||||
|
use content_type::ContentType;
|
||||||
|
use super::{Collider, URI, URIBuf}; // :D
|
||||||
|
|
||||||
use term_painter::ToStyle;
|
use term_painter::ToStyle;
|
||||||
use term_painter::Color::*;
|
use term_painter::Color::*;
|
||||||
use method::Method;
|
|
||||||
use super::{Collider, URI, URIBuf}; // :D
|
|
||||||
use handler::Handler;
|
|
||||||
use codegen::StaticRouteInfo;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
|
|
||||||
|
@ -11,17 +12,19 @@ pub struct Route {
|
||||||
pub method: Method,
|
pub method: Method,
|
||||||
pub handler: Handler,
|
pub handler: Handler,
|
||||||
pub path: URIBuf,
|
pub path: URIBuf,
|
||||||
pub rank: isize
|
pub rank: isize,
|
||||||
|
pub content_type: ContentType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Route {
|
impl Route {
|
||||||
pub fn ranked<S>(rank: isize, m: Method, path: S, handler: Handler)
|
pub fn ranked<S>(rank: isize, m: Method, path: S, handler: Handler, t: ContentType)
|
||||||
-> Route where S: AsRef<str> {
|
-> Route where S: AsRef<str> {
|
||||||
Route {
|
Route {
|
||||||
method: m,
|
method: m,
|
||||||
path: URIBuf::from(path.as_ref()),
|
path: URIBuf::from(path.as_ref()),
|
||||||
handler: handler,
|
handler: handler,
|
||||||
rank: rank
|
rank: rank,
|
||||||
|
content_type: t,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +35,7 @@ impl Route {
|
||||||
handler: handler,
|
handler: handler,
|
||||||
rank: (!path.as_ref().contains('<') as isize),
|
rank: (!path.as_ref().contains('<') as isize),
|
||||||
path: URIBuf::from(path.as_ref()),
|
path: URIBuf::from(path.as_ref()),
|
||||||
|
content_type: ContentType::any(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use syntax::codemap::{Span, Spanned, BytePos};
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
|
|
||||||
use utils::*;
|
use utils::*;
|
||||||
use rocket::Method;
|
use rocket::{Method, ContentType};
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
const DEBUG: bool = true;
|
const DEBUG: bool = true;
|
||||||
|
@ -122,7 +122,7 @@ pub struct RouteParams {
|
||||||
pub method: Spanned<Method>,
|
pub method: Spanned<Method>,
|
||||||
pub path: KVSpanned<String>,
|
pub path: KVSpanned<String>,
|
||||||
pub form: Option<KVSpanned<String>>,
|
pub form: Option<KVSpanned<String>>,
|
||||||
pub content_type: Option<KVSpanned<String>>,
|
pub content_type: Option<KVSpanned<ContentType>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait RouteDecoratorExt {
|
pub trait RouteDecoratorExt {
|
||||||
|
@ -206,7 +206,18 @@ impl<'a, 'c> RouteDecoratorExt for MetaItemParser<'a, 'c> {
|
||||||
});
|
});
|
||||||
|
|
||||||
let content_type = kv_pairs.get("content").and_then(|data| {
|
let content_type = kv_pairs.get("content").and_then(|data| {
|
||||||
Some(data.clone().map(String::from))
|
if let Ok(ct) = ContentType::from_str(data.node) {
|
||||||
|
if ct.is_ext() {
|
||||||
|
let msg = format!("'{}' is not a known content-type", data.node);
|
||||||
|
self.ctxt.span_warn(data.v_span, &msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(data.clone().map(|_| ct))
|
||||||
|
} else {
|
||||||
|
let msg = format!("'{}' is not a valid content-type", data.node);
|
||||||
|
self.ctxt.span_err(data.v_span, &msg);
|
||||||
|
None
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
debug!("Found data: {:?}", content_type);
|
debug!("Found data: {:?}", content_type);
|
||||||
|
|
|
@ -217,7 +217,11 @@ pub fn route_decorator(known_method: Option<Spanned<Method>>, ecx: &mut ExtCtxt,
|
||||||
::rocket::StaticRouteInfo {
|
::rocket::StaticRouteInfo {
|
||||||
method: $method,
|
method: $method,
|
||||||
path: $path,
|
path: $path,
|
||||||
handler: $route_fn_name
|
handler: $route_fn_name,
|
||||||
|
content_type: ::rocket::ContentType(
|
||||||
|
::rocket::content_type::TopLevel::Star,
|
||||||
|
::rocket::content_type::SubLevel::Star,
|
||||||
|
None)
|
||||||
};
|
};
|
||||||
).unwrap()));
|
).unwrap()));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue