mirror of https://github.com/rwf2/Rocket.git
Use full URI in codegen routes; log query params in routes.
This commit is contained in:
parent
ecd72f686e
commit
e966925455
|
@ -45,7 +45,7 @@ trait RouteGenerateExt {
|
|||
fn generate_query_statement(&self, ecx: &ExtCtxt) -> Option<Stmt>;
|
||||
fn generate_param_statements(&self, ecx: &ExtCtxt) -> Vec<Stmt>;
|
||||
fn generate_fn_arguments(&self, ecx: &ExtCtxt) -> Vec<TokenTree>;
|
||||
fn explode(&self, ecx: &ExtCtxt) -> (&String, Path, P<Expr>, P<Expr>);
|
||||
fn explode(&self, ecx: &ExtCtxt) -> (&str, Path, P<Expr>, P<Expr>);
|
||||
}
|
||||
|
||||
impl RouteGenerateExt for RouteParams {
|
||||
|
@ -217,8 +217,8 @@ impl RouteGenerateExt for RouteParams {
|
|||
sep_by_tok(ecx, &args, token::Comma)
|
||||
}
|
||||
|
||||
fn explode(&self, ecx: &ExtCtxt) -> (&String, Path, P<Expr>, P<Expr>) {
|
||||
let path = &self.path.node;
|
||||
fn explode(&self, ecx: &ExtCtxt) -> (&str, Path, P<Expr>, P<Expr>) {
|
||||
let path = &self.uri.node.as_str();
|
||||
let method = method_to_path(ecx, self.method.node);
|
||||
let format = self.format.as_ref().map(|kv| kv.value().clone());
|
||||
let content_type = option_as_expr(ecx, &content_type_to_expr(ecx, format));
|
||||
|
|
|
@ -9,6 +9,7 @@ use utils::{span, MetaItemExt, SpanExt, is_valid_ident};
|
|||
use super::{Function, ParamIter};
|
||||
use super::keyvalue::KVSpanned;
|
||||
use rocket::http::{Method, ContentType};
|
||||
use rocket::http::uri::URI;
|
||||
|
||||
/// This structure represents the parsed `route` attribute.
|
||||
///
|
||||
|
@ -20,7 +21,7 @@ use rocket::http::{Method, ContentType};
|
|||
pub struct RouteParams {
|
||||
pub annotated_fn: Function,
|
||||
pub method: Spanned<Method>,
|
||||
pub path: Spanned<String>,
|
||||
pub uri: Spanned<URI<'static>>,
|
||||
pub data_param: Option<KVSpanned<Ident>>,
|
||||
pub query_param: Option<Spanned<Ident>>,
|
||||
pub format: Option<KVSpanned<ContentType>>,
|
||||
|
@ -69,7 +70,7 @@ impl RouteParams {
|
|||
}
|
||||
|
||||
// Parse the required path and optional query parameters.
|
||||
let (path, query) = parse_path(ecx, &attr_params[0]);
|
||||
let (uri, query) = parse_path(ecx, &attr_params[0]);
|
||||
|
||||
// Parse all of the optional parameters.
|
||||
let mut seen_keys = HashSet::new();
|
||||
|
@ -115,7 +116,7 @@ impl RouteParams {
|
|||
|
||||
RouteParams {
|
||||
method: method,
|
||||
path: path,
|
||||
uri: uri,
|
||||
data_param: data,
|
||||
query_param: query,
|
||||
format: format,
|
||||
|
@ -127,7 +128,7 @@ impl RouteParams {
|
|||
pub fn path_params<'s, 'a, 'c: 'a>(&'s self,
|
||||
ecx: &'a ExtCtxt<'c>)
|
||||
-> ParamIter<'s, 'a, 'c> {
|
||||
ParamIter::new(ecx, self.path.node.as_str(), self.path.span.trim(1))
|
||||
ParamIter::new(ecx, self.uri.node.path(), self.uri.span.trim(1))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,12 +151,12 @@ pub fn kv_from_nested(item: &NestedMetaItem) -> Option<KVSpanned<LitKind>> {
|
|||
})
|
||||
}
|
||||
|
||||
fn param_string_to_ident(ecx: &ExtCtxt, s: Spanned<&str>) -> Option<Ident> {
|
||||
fn param_string_to_ident(ecx: &ExtCtxt, s: Spanned<&str>) -> Option<Spanned<Ident>> {
|
||||
let string = s.node;
|
||||
if string.starts_with('<') && string.ends_with('>') {
|
||||
let param = &string[1..(string.len() - 1)];
|
||||
if is_valid_ident(param) {
|
||||
return Some(Ident::from_str(param));
|
||||
return Some(span(Ident::from_str(param), s.span.trim(1)));
|
||||
}
|
||||
|
||||
ecx.span_err(s.span, "parameter name must be alphanumeric");
|
||||
|
@ -186,16 +187,14 @@ fn parse_method(ecx: &ExtCtxt, meta_item: &NestedMetaItem) -> Spanned<Method> {
|
|||
dummy_spanned(Method::Get)
|
||||
}
|
||||
|
||||
fn parse_path(ecx: &ExtCtxt, meta_item: &NestedMetaItem) -> (Spanned<String>, Option<Spanned<Ident>>) {
|
||||
fn parse_path(ecx: &ExtCtxt, meta_item: &NestedMetaItem)
|
||||
-> (Spanned<URI<'static>>, Option<Spanned<Ident>>) {
|
||||
let from_string = |string: &str, sp: Span| {
|
||||
if let Some(q) = string.find('?') {
|
||||
let path = span(string[..q].to_string(), sp);
|
||||
let q_str = span(&string[(q + 1)..], sp);
|
||||
let query = param_string_to_ident(ecx, q_str).map(|i| span(i, sp));
|
||||
return (path, query);
|
||||
} else {
|
||||
return (span(string.to_string(), sp), None)
|
||||
}
|
||||
let query_param = string.find('?')
|
||||
.map(|i| span(&string[(i + 1)..], sp.trim_left(i + 1)))
|
||||
.and_then(|spanned_q_param| param_string_to_ident(ecx, spanned_q_param));
|
||||
|
||||
(span(URI::from(string.to_string()), sp), query_param)
|
||||
};
|
||||
|
||||
let sp = meta_item.span();
|
||||
|
@ -217,7 +216,7 @@ fn parse_path(ecx: &ExtCtxt, meta_item: &NestedMetaItem) -> (Spanned<String>, Op
|
|||
.emit();
|
||||
}
|
||||
|
||||
(dummy_spanned("".to_string()), None)
|
||||
(dummy_spanned(URI::new("")), None)
|
||||
}
|
||||
|
||||
fn parse_opt<O, T, F>(ecx: &ExtCtxt, kv: &KVSpanned<T>, f: F) -> Option<KVSpanned<O>>
|
||||
|
@ -230,8 +229,8 @@ fn parse_data(ecx: &ExtCtxt, kv: &KVSpanned<LitKind>) -> Ident {
|
|||
let mut ident = Ident::from_str("unknown");
|
||||
if let LitKind::Str(ref s, _) = *kv.value() {
|
||||
ident = Ident::from_str(&s.as_str());
|
||||
if let Some(ident) = param_string_to_ident(ecx, span(&s.as_str(), kv.value.span)) {
|
||||
return ident;
|
||||
if let Some(id) = param_string_to_ident(ecx, span(&s.as_str(), kv.value.span)) {
|
||||
return id.node;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,17 @@ pub trait SpanExt {
|
|||
|
||||
/// Trim the span on the left and right by `length`.
|
||||
fn trim(self, length: u32) -> Span;
|
||||
|
||||
/// Trim the span on the left by `length`.
|
||||
fn trim_left(self, length: usize) -> Span;
|
||||
}
|
||||
|
||||
impl SpanExt for Span {
|
||||
fn trim_left(mut self, length: usize) -> Span {
|
||||
self.lo = self.lo + BytePos(length as u32);
|
||||
self
|
||||
}
|
||||
|
||||
fn shorten_to(mut self, to_length: usize) -> Span {
|
||||
self.hi = self.lo + BytePos(to_length as u32);
|
||||
self
|
||||
|
|
|
@ -276,11 +276,11 @@ impl<'a> fmt::Display for URI<'a> {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// If this is the root path, then there are "zero" segments.
|
||||
if self.as_str().starts_with('/') && self.segment_count() == 0 {
|
||||
return write!(f, "/");
|
||||
}
|
||||
|
||||
for segment in self.segments() {
|
||||
write!(f, "/{}", segment)?;
|
||||
write!(f, "/")?;
|
||||
} else {
|
||||
for segment in self.segments() {
|
||||
write!(f, "/{}", segment)?;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(query_str) = self.query() {
|
||||
|
|
Loading…
Reference in New Issue