Created
August 10, 2019 13:51
-
-
Save nathansamson/85f7ccb52044f45aa85f8faf6ca9f1af to your computer and use it in GitHub Desktop.
Basic form handing in Rocket
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(proc_macro_hygiene, decl_macro)] | |
#[macro_use] extern crate rocket; | |
use rocket::request::{Form, FromFormValue}; | |
use rocket::http::RawStr; | |
use rocket_contrib::serve::StaticFiles; | |
use rocket_contrib::templates::Template; | |
use serde::Serialize; | |
#[derive(Serialize)] | |
struct NullContext { } | |
#[derive(Serialize)] | |
struct LoginFormContext { | |
login_form_url: String, | |
login_fields: Option<LoginFields>, | |
} | |
#[derive(Clone)] | |
struct ValidEmail<'r>(&'r str); | |
#[derive(Serialize)] | |
struct LoginFields { | |
email: String, | |
email_error: Option<String>, | |
password: String, | |
password_error: Option<String>, | |
} | |
#[derive(Clone)] | |
struct ErrWithOriginal(String, String); | |
impl std::fmt::Debug for ErrWithOriginal { | |
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
write!(f, "ErrWithOriginal {{ err: {}, original: {} }}", self.0, self.1) | |
} | |
} | |
#[derive(FromForm)] | |
struct LoginForm<'r> { | |
email: Result<ValidEmail<'r>, ErrWithOriginal>, | |
password: String, | |
} | |
impl<'v> FromFormValue<'v> for ValidEmail<'v> { | |
type Error = ErrWithOriginal; | |
fn from_form_value(v: &'v RawStr) -> Result<Self, ErrWithOriginal> { | |
println!("Incoming email {}", v.url_decode().unwrap()); | |
if v.url_decode().unwrap() == "nathan@nathansamson.be" { | |
Ok(ValidEmail(v.as_str())) | |
} else { | |
Err(ErrWithOriginal("Not me".to_string(), v.url_decode().unwrap().to_string())) | |
} | |
} | |
} | |
#[post("/login", data = "<login>")] | |
fn login(login: Form<LoginForm>) -> Template { | |
if login.email.is_ok() { | |
let context = NullContext { }; | |
Template::render("index/dashboard", &context) | |
} else { | |
let context = LoginFormContext { | |
login_form_url: uri!(login).to_string(), | |
login_fields: Some(LoginFields { | |
email: if login.email.is_ok() { (login.email.clone().unwrap().0).to_string() } else { (login.email.clone().err().unwrap()).1 }, | |
email_error: if login.email.is_err() { Some((login.email.clone().err().unwrap()).0) } else { None }, | |
password: login.password.clone(), | |
password_error: None }), | |
}; | |
Template::render("index/login", &context) | |
} | |
} | |
#[get("/")] | |
fn index() -> Template { | |
let context = LoginFormContext { | |
login_form_url: uri!(login).to_string(), | |
login_fields: None, | |
}; | |
Template::render("index/login", &context) | |
} | |
fn main() { | |
rocket::ignite(). | |
attach(Template::fairing()). | |
mount("/public", StaticFiles::from("./dist")). | |
mount("/", routes![index, login]).launch(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment