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_query_statement(&self, ecx: &ExtCtxt) -> Option<Stmt>;
|
||||||
fn generate_param_statements(&self, ecx: &ExtCtxt) -> Vec<Stmt>;
|
fn generate_param_statements(&self, ecx: &ExtCtxt) -> Vec<Stmt>;
|
||||||
fn generate_fn_arguments(&self, ecx: &ExtCtxt) -> Vec<TokenTree>;
|
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 {
|
impl RouteGenerateExt for RouteParams {
|
||||||
|
@ -217,8 +217,8 @@ impl RouteGenerateExt for RouteParams {
|
||||||
sep_by_tok(ecx, &args, token::Comma)
|
sep_by_tok(ecx, &args, token::Comma)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn explode(&self, ecx: &ExtCtxt) -> (&String, Path, P<Expr>, P<Expr>) {
|
fn explode(&self, ecx: &ExtCtxt) -> (&str, Path, P<Expr>, P<Expr>) {
|
||||||
let path = &self.path.node;
|
let path = &self.uri.node.as_str();
|
||||||
let method = method_to_path(ecx, self.method.node);
|
let method = method_to_path(ecx, self.method.node);
|
||||||
let format = self.format.as_ref().map(|kv| kv.value().clone());
|
let format = self.format.as_ref().map(|kv| kv.value().clone());
|
||||||
let content_type = option_as_expr(ecx, &content_type_to_expr(ecx, format));
|
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::{Function, ParamIter};
|
||||||
use super::keyvalue::KVSpanned;
|
use super::keyvalue::KVSpanned;
|
||||||
use rocket::http::{Method, ContentType};
|
use rocket::http::{Method, ContentType};
|
||||||
|
use rocket::http::uri::URI;
|
||||||
|
|
||||||
/// This structure represents the parsed `route` attribute.
|
/// This structure represents the parsed `route` attribute.
|
||||||
///
|
///
|
||||||
|
@ -20,7 +21,7 @@ use rocket::http::{Method, ContentType};
|
||||||
pub struct RouteParams {
|
pub struct RouteParams {
|
||||||
pub annotated_fn: Function,
|
pub annotated_fn: Function,
|
||||||
pub method: Spanned<Method>,
|
pub method: Spanned<Method>,
|
||||||
pub path: Spanned<String>,
|
pub uri: Spanned<URI<'static>>,
|
||||||
pub data_param: Option<KVSpanned<Ident>>,
|
pub data_param: Option<KVSpanned<Ident>>,
|
||||||
pub query_param: Option<Spanned<Ident>>,
|
pub query_param: Option<Spanned<Ident>>,
|
||||||
pub format: Option<KVSpanned<ContentType>>,
|
pub format: Option<KVSpanned<ContentType>>,
|
||||||
|
@ -69,7 +70,7 @@ impl RouteParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the required path and optional query parameters.
|
// 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.
|
// Parse all of the optional parameters.
|
||||||
let mut seen_keys = HashSet::new();
|
let mut seen_keys = HashSet::new();
|
||||||
|
@ -115,7 +116,7 @@ impl RouteParams {
|
||||||
|
|
||||||
RouteParams {
|
RouteParams {
|
||||||
method: method,
|
method: method,
|
||||||
path: path,
|
uri: uri,
|
||||||
data_param: data,
|
data_param: data,
|
||||||
query_param: query,
|
query_param: query,
|
||||||
format: format,
|
format: format,
|
||||||
|
@ -127,7 +128,7 @@ impl RouteParams {
|
||||||
pub fn path_params<'s, 'a, 'c: 'a>(&'s self,
|
pub fn path_params<'s, 'a, 'c: 'a>(&'s self,
|
||||||
ecx: &'a ExtCtxt<'c>)
|
ecx: &'a ExtCtxt<'c>)
|
||||||
-> ParamIter<'s, 'a, '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;
|
let string = s.node;
|
||||||
if string.starts_with('<') && string.ends_with('>') {
|
if string.starts_with('<') && string.ends_with('>') {
|
||||||
let param = &string[1..(string.len() - 1)];
|
let param = &string[1..(string.len() - 1)];
|
||||||
if is_valid_ident(param) {
|
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");
|
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)
|
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| {
|
let from_string = |string: &str, sp: Span| {
|
||||||
if let Some(q) = string.find('?') {
|
let query_param = string.find('?')
|
||||||
let path = span(string[..q].to_string(), sp);
|
.map(|i| span(&string[(i + 1)..], sp.trim_left(i + 1)))
|
||||||
let q_str = span(&string[(q + 1)..], sp);
|
.and_then(|spanned_q_param| param_string_to_ident(ecx, spanned_q_param));
|
||||||
let query = param_string_to_ident(ecx, q_str).map(|i| span(i, sp));
|
|
||||||
return (path, query);
|
(span(URI::from(string.to_string()), sp), query_param)
|
||||||
} else {
|
|
||||||
return (span(string.to_string(), sp), None)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let sp = meta_item.span();
|
let sp = meta_item.span();
|
||||||
|
@ -217,7 +216,7 @@ fn parse_path(ecx: &ExtCtxt, meta_item: &NestedMetaItem) -> (Spanned<String>, Op
|
||||||
.emit();
|
.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>>
|
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");
|
let mut ident = Ident::from_str("unknown");
|
||||||
if let LitKind::Str(ref s, _) = *kv.value() {
|
if let LitKind::Str(ref s, _) = *kv.value() {
|
||||||
ident = Ident::from_str(&s.as_str());
|
ident = Ident::from_str(&s.as_str());
|
||||||
if let Some(ident) = param_string_to_ident(ecx, span(&s.as_str(), kv.value.span)) {
|
if let Some(id) = param_string_to_ident(ecx, span(&s.as_str(), kv.value.span)) {
|
||||||
return ident;
|
return id.node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,17 @@ pub trait SpanExt {
|
||||||
|
|
||||||
/// Trim the span on the left and right by `length`.
|
/// Trim the span on the left and right by `length`.
|
||||||
fn trim(self, length: u32) -> Span;
|
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 {
|
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 {
|
fn shorten_to(mut self, to_length: usize) -> Span {
|
||||||
self.hi = self.lo + BytePos(to_length as u32);
|
self.hi = self.lo + BytePos(to_length as u32);
|
||||||
self
|
self
|
||||||
|
|
|
@ -276,11 +276,11 @@ impl<'a> fmt::Display for URI<'a> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
// If this is the root path, then there are "zero" segments.
|
// If this is the root path, then there are "zero" segments.
|
||||||
if self.as_str().starts_with('/') && self.segment_count() == 0 {
|
if self.as_str().starts_with('/') && self.segment_count() == 0 {
|
||||||
return write!(f, "/");
|
write!(f, "/")?;
|
||||||
}
|
} else {
|
||||||
|
for segment in self.segments() {
|
||||||
for segment in self.segments() {
|
write!(f, "/{}", segment)?;
|
||||||
write!(f, "/{}", segment)?;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(query_str) = self.query() {
|
if let Some(query_str) = self.query() {
|
||||||
|
|
Loading…
Reference in New Issue