Fixed codegen to work with new API.

This commit is contained in:
Sergio Benitez 2016-04-03 04:25:37 -07:00
parent 3dfa049a1a
commit 293159904f
5 changed files with 55 additions and 17 deletions

View File

@ -5,6 +5,11 @@ extern crate rocket;
use rocket::Rocket; use rocket::Rocket;
use rocket::response::Redirect; use rocket::response::Redirect;
#[route(GET, path = "/")]
fn root() -> Redirect {
Redirect::to("/users/login")
}
#[route(GET, path = "/users/<name>")] #[route(GET, path = "/users/<name>")]
fn user(name: &str) -> Result<&'static str, Redirect> { fn user(name: &str) -> Result<&'static str, Redirect> {
match name { match name {
@ -19,5 +24,6 @@ fn login() -> &'static str {
} }
fn main() { fn main() {
Rocket::new("localhost", 8000).mount_and_launch("/", routes![user, login]); let rocket = Rocket::new("localhost", 8000);
rocket.mount_and_launch("/", routes![root, user, login]);
} }

View File

@ -1,9 +1,11 @@
use term_painter::ToStyle; use term_painter::ToStyle;
use term_painter::Color::*; use term_painter::Color::*;
use std::fmt;
use method::Method; use method::Method;
use super::{Collider, URI, URIBuf}; // :D use super::{Collider, URI, URIBuf}; // :D
use handler::Handler; use handler::Handler;
use codegen::StaticRouteInfo;
use std::fmt;
use std::convert::From;
pub struct Route { pub struct Route {
pub method: Method, pub method: Method,
@ -61,6 +63,12 @@ impl fmt::Display for Route {
} }
} }
impl<'a> From<&'a StaticRouteInfo> for Route {
fn from(info: &'a StaticRouteInfo) -> Route {
Route::new(info.method, info.path, info.handler)
}
}
impl Collider for Route { impl Collider for Route {
fn collides_with(&self, b: &Route) -> bool { fn collides_with(&self, b: &Route) -> bool {
if self.path.segment_count() != b.path.segment_count() if self.path.segment_count() != b.path.segment_count()

View File

@ -5,7 +5,7 @@ use std::str::FromStr;
use std::collections::HashSet; use std::collections::HashSet;
use syntax::ext::quote::rt::ToTokens; use syntax::ext::quote::rt::ToTokens;
use syntax::codemap::{Span, BytePos, DUMMY_SP, Spanned}; use syntax::codemap::{Span, BytePos, /* DUMMY_SP, */ Spanned};
use syntax::ast::{Ident, TokenTree, PatKind, Stmt}; use syntax::ast::{Ident, TokenTree, PatKind, Stmt};
use syntax::ast::{Item, Expr, ItemKind, MetaItem, MetaItemKind, FnDecl, Ty}; use syntax::ast::{Item, Expr, ItemKind, MetaItem, MetaItemKind, FnDecl, Ty};
use syntax::ext::base::{Annotatable, ExtCtxt}; use syntax::ext::base::{Annotatable, ExtCtxt};
@ -215,6 +215,12 @@ impl SimpleArg {
} }
} }
impl ToTokens for SimpleArg {
fn to_tokens(&self, cx: &ExtCtxt) -> Vec<TokenTree> {
str_to_ident(self.as_str()).to_tokens(cx)
}
}
fn get_fn_params<'a>(ecx: &ExtCtxt, dec_span: Span, path: &'a KVSpanned<String>, fn get_fn_params<'a>(ecx: &ExtCtxt, dec_span: Span, path: &'a KVSpanned<String>,
fn_decl: &Spanned<&FnDecl>, mut external: HashSet<&'a str>) fn_decl: &Spanned<&FnDecl>, mut external: HashSet<&'a str>)
-> Vec<SimpleArg> { -> Vec<SimpleArg> {
@ -330,14 +336,7 @@ pub fn route_decorator(ecx: &mut ExtCtxt, sp: Span, meta_item: &MetaItem,
// Create a comma seperated list (token tree) of the function parameters // Create a comma seperated list (token tree) of the function parameters
// We pass this in to the user's function that we're wrapping. // We pass this in to the user's function that we're wrapping.
let mut fn_param_idents: Vec<TokenTree> = vec![]; let fn_param_idents = token_separate(ecx, &fn_params, token::Comma);
for i in 0..fn_params.len() {
let tokens = str_to_ident(fn_params[i].as_str()).to_tokens(ecx);
fn_param_idents.extend(tokens);
if i < fn_params.len() - 1 {
fn_param_idents.push(TokenTree::Token(DUMMY_SP, token::Comma));
}
}
// Generate the statements that will attempt to parse forms during run-time. // Generate the statements that will attempt to parse forms during run-time.
// let form_span = route_params.form.map_or(DUMMY_SP, |f| f.span.clone()); // let form_span = route_params.form.map_or(DUMMY_SP, |f| f.span.clone());

View File

@ -1,13 +1,15 @@
use super::{STRUCT_PREFIX}; use super::{STRUCT_PREFIX};
use utils::prepend_ident; use utils::{prepend_ident, token_separate};
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::ast::{Path, TokenTree}; use syntax::ast::{Path, TokenTree, Expr};
use syntax::ext::base::{ExtCtxt, MacResult, MacEager}; use syntax::ext::base::{ExtCtxt, MacResult, MacEager};
use syntax::ext::build::AstBuilder; use syntax::ext::build::AstBuilder;
use syntax::parse::parser::{Parser, PathParsingMode}; use syntax::parse::parser::{Parser, PathParsingMode};
use syntax::parse::PResult; use syntax::parse::PResult;
use syntax::parse::token::Token; use syntax::parse::token::Token;
use syntax::ptr::P;
const DEBUG: bool = false;
fn get_paths<'a>(parser: &mut Parser<'a>) -> PResult<'a, Vec<Path>> { fn get_paths<'a>(parser: &mut Parser<'a>) -> PResult<'a, Vec<Path>> {
if parser.eat(&Token::Eof) { if parser.eat(&Token::Eof) {
@ -26,7 +28,7 @@ fn get_paths<'a>(parser: &mut Parser<'a>) -> PResult<'a, Vec<Path>> {
Ok(results) Ok(results)
} }
pub fn routes_macro(ecx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) pub fn routes_macro(ecx: &mut ExtCtxt, _sp: Span, args: &[TokenTree])
-> Box<MacResult + 'static> { -> Box<MacResult + 'static> {
let mut parser = ecx.new_parser_from_tts(args); let mut parser = ecx.new_parser_from_tts(args);
let mut paths = get_paths(&mut parser).unwrap_or_else(|mut e| { let mut paths = get_paths(&mut parser).unwrap_or_else(|mut e| {
@ -42,7 +44,15 @@ pub fn routes_macro(ecx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
last_seg.identifier = new_ident; last_seg.identifier = new_ident;
} }
debug!("Found paths: {:?}", paths);
// Build up the P<Expr> for each path. // Build up the P<Expr> for each path.
let path_exprs = paths.iter().map(|p| { quote_expr!(ecx, &$p) }).collect(); let path_exprs: Vec<P<Expr>> = paths.iter().map(|p| {
MacEager::expr(ecx.expr_vec_slice(sp, path_exprs)) quote_expr!(ecx, rocket::Route::from(&$p))
}).collect();
debug!("Path Exprs: {:?}", path_exprs);
// Now put them all in one vector and return the thing.
let path_list = token_separate(ecx, &path_exprs, Token::Comma);
let output = quote_expr!(ecx, vec![$path_list]).unwrap();
MacEager::expr(P(output))
} }

View File

@ -1,4 +1,5 @@
use syntax::parse::{token}; use syntax::parse::{token};
use syntax::parse::token::Token;
use syntax::ast::{Ident, MetaItem, MetaItemKind, LitKind, TokenTree}; use syntax::ast::{Ident, MetaItem, MetaItemKind, LitKind, TokenTree};
use syntax::ext::base::{ExtCtxt}; use syntax::ext::base::{ExtCtxt};
use syntax::codemap::{Span, Spanned, BytePos, DUMMY_SP}; use syntax::codemap::{Span, Spanned, BytePos, DUMMY_SP};
@ -138,6 +139,20 @@ pub fn get_key_values<'b>(ecx: &mut ExtCtxt, sp: Span, required: &[&str],
kv_pairs kv_pairs
} }
pub fn token_separate<T: ToTokens>(ecx: &ExtCtxt, things: &Vec<T>,
token: Token) -> Vec<TokenTree> {
let mut output: Vec<TokenTree> = vec![];
for (i, thing) in things.iter().enumerate() {
output.extend(thing.to_tokens(ecx));
if i < things.len() - 1 {
output.push(TokenTree::Token(DUMMY_SP, token.clone()));
}
}
output
}
// pub fn find_value_for(key: &str, kv_params: &[P<MetaItem>]) -> Option<String> { // pub fn find_value_for(key: &str, kv_params: &[P<MetaItem>]) -> Option<String> {
// for param in kv_params { // for param in kv_params {
// if let MetaItemKind::NameValue(ref name, ref value) = param.node { // if let MetaItemKind::NameValue(ref name, ref value) = param.node {