2016-03-28 09:34:09 +00:00
|
|
|
#![feature(plugin)]
|
|
|
|
#![plugin(rocket_macros)]
|
|
|
|
|
|
|
|
extern crate rocket;
|
|
|
|
|
2016-03-30 08:02:21 +00:00
|
|
|
mod files;
|
|
|
|
|
2016-03-28 09:34:09 +00:00
|
|
|
use rocket::Rocket;
|
|
|
|
use rocket::response::Redirect;
|
2016-04-01 23:54:53 +00:00
|
|
|
use rocket::Error;
|
2016-04-04 05:41:31 +00:00
|
|
|
use rocket::form::{FromForm, FromFormValue, form_items};
|
2016-03-28 09:34:09 +00:00
|
|
|
|
2016-03-30 08:02:21 +00:00
|
|
|
#[route(GET, path = "/user/<username>")]
|
|
|
|
fn user_page(username: &str) -> String {
|
|
|
|
format!("This is {}'s page.", username)
|
2016-03-28 09:34:09 +00:00
|
|
|
}
|
|
|
|
|
2016-04-04 04:53:25 +00:00
|
|
|
// #[derive(FromForm)] // FIXME: Make that happen.
|
2016-03-30 08:02:21 +00:00
|
|
|
struct UserLogin<'a> {
|
|
|
|
username: &'a str,
|
2016-04-04 05:41:31 +00:00
|
|
|
password: &'a str,
|
|
|
|
age: Result<isize, &'a str>,
|
2016-03-28 09:34:09 +00:00
|
|
|
}
|
|
|
|
|
2016-04-04 04:53:25 +00:00
|
|
|
// will help for validation. IE, can have a type Range(1, 10) that returns an
|
|
|
|
// enum with one of: TooLow(isize), TooHigh(isize), etc.
|
|
|
|
impl<'f> FromForm<'f> for UserLogin<'f> {
|
|
|
|
fn from_form_string(s: &'f str) -> Result<Self, Error> {
|
2016-04-04 05:41:31 +00:00
|
|
|
let mut items = [("", ""); 3];
|
2016-04-04 04:53:25 +00:00
|
|
|
let form_count = form_items(s, &mut items);
|
2016-04-04 05:41:31 +00:00
|
|
|
if form_count != items.len() {
|
2016-04-04 04:53:25 +00:00
|
|
|
return Err(Error::BadParse);
|
|
|
|
}
|
|
|
|
|
2016-04-04 05:41:31 +00:00
|
|
|
let mut username: Option<&'f str> = None;
|
|
|
|
let mut password: Option<&'f str> = None;
|
|
|
|
let mut age: Option<Result<isize, &'f str>> = None;
|
2016-04-04 04:53:25 +00:00
|
|
|
for &(key, value) in &items {
|
|
|
|
match key {
|
2016-04-04 05:41:31 +00:00
|
|
|
"username" => username = match FromFormValue::parse(value) {
|
|
|
|
Ok(v) => Some(v),
|
|
|
|
Err(_) => return Err(Error::BadParse)
|
|
|
|
},
|
|
|
|
"password" => password = match FromFormValue::parse(value) {
|
|
|
|
Ok(v) => Some(v),
|
|
|
|
Err(_) => return Err(Error::BadParse)
|
|
|
|
},
|
|
|
|
"age" => age = match FromFormValue::parse(value) {
|
|
|
|
Ok(v) => Some(v),
|
|
|
|
Err(_) => return Err(Error::BadParse)
|
|
|
|
},
|
2016-04-04 04:53:25 +00:00
|
|
|
_ => return Err(Error::BadParse)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if username.is_none() || password.is_none() {
|
|
|
|
return Err(Error::BadParse);
|
|
|
|
}
|
|
|
|
|
2016-03-30 08:02:21 +00:00
|
|
|
Ok(UserLogin {
|
2016-04-04 04:53:25 +00:00
|
|
|
username: username.unwrap(),
|
2016-04-04 05:41:31 +00:00
|
|
|
password: password.unwrap(),
|
|
|
|
age: age.unwrap(),
|
2016-03-30 08:02:21 +00:00
|
|
|
})
|
|
|
|
}
|
2016-03-28 09:34:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Actually look at form parameters.
|
2016-03-30 08:02:21 +00:00
|
|
|
// FIXME: fn login<'a>(user: UserLogin<'a>)
|
|
|
|
#[route(POST, path = "/login", form = "<user>")]
|
|
|
|
fn login(user: UserLogin) -> Result<Redirect, String> {
|
2016-04-04 05:41:31 +00:00
|
|
|
if user.age.is_err() {
|
|
|
|
let input = user.age.unwrap_err();
|
|
|
|
return Err(format!("'{}' is not a valid age integer.", input));
|
|
|
|
}
|
|
|
|
|
|
|
|
if user.age.unwrap() < 20 {
|
|
|
|
return Err(format!("Sorry, {} is too young!", user.age.unwrap()));
|
|
|
|
}
|
|
|
|
|
2016-03-30 08:02:21 +00:00
|
|
|
match user.username {
|
|
|
|
"Sergio" => match user.password {
|
2016-04-04 04:53:25 +00:00
|
|
|
"password" => Ok(Redirect::other("/user/Sergio")),
|
2016-03-30 08:02:21 +00:00
|
|
|
_ => Err("Wrong password!".to_string())
|
|
|
|
},
|
|
|
|
_ => Err(format!("Unrecognized user, '{}'.", user.username))
|
2016-03-28 09:34:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
2016-03-30 08:02:21 +00:00
|
|
|
let mut rocket = Rocket::new("localhost", 8000);
|
|
|
|
rocket.mount("/", routes![files::index, files::files, user_page, login]);
|
|
|
|
rocket.launch();
|
2016-03-28 09:34:09 +00:00
|
|
|
}
|