#![feature(plugin, custom_derive)] #![plugin(rocket_macros)] extern crate rocket; mod files; use rocket::Rocket; use rocket::response::Redirect; use rocket::form::FromFormValue; #[derive(Debug)] struct StrongPassword<'r>(&'r str); #[derive(Debug)] struct AdultAge(isize); #[derive(FromForm)] struct UserLogin<'r> { username: &'r str, password: Result, &'r str>, age: Result, } impl<'v> FromFormValue<'v> for StrongPassword<'v> { type Error = &'static str; fn parse(v: &'v str) -> Result { if v.len() < 8 { Err("Too short!") } else { Ok(StrongPassword(v)) } } } impl<'v> FromFormValue<'v> for AdultAge { type Error = &'static str; fn parse(v: &'v str) -> Result { let age = match isize::parse(v) { Ok(v) => v, Err(_) => return Err("Age value is not a number.") }; match age > 20 { true => Ok(AdultAge(age)), false => Err("Must be at least 21.") } } } #[route(POST, path = "/login", form = "")] fn login(user: UserLogin) -> Result { if user.age.is_err() { return Err(String::from(user.age.unwrap_err())); } if user.password.is_err() { return Err(String::from(user.password.unwrap_err())); } match user.username { "Sergio" => match user.password.unwrap().0 { "password" => Ok(Redirect::other("/user/Sergio")), _ => Err("Wrong password!".to_string()) }, _ => Err(format!("Unrecognized user, '{}'.", user.username)) } } #[route(GET, path = "/user/")] fn user_page(username: &str) -> String { format!("This is {}'s page.", username) } fn main() { let mut rocket = Rocket::new("localhost", 8000); rocket.mount("/", routes![files::index, files::files, user_page, login]); rocket.launch(); }