diff options
-rw-r--r-- | src/handlers/mod.rs | 70 | ||||
-rw-r--r-- | src/main.rs | 82 | ||||
-rw-r--r-- | src/models/mod.rs | 2 |
3 files changed, 82 insertions, 72 deletions
diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs new file mode 100644 index 0000000..efd99f5 --- /dev/null +++ b/src/handlers/mod.rs @@ -0,0 +1,70 @@ +use crate::templates; +use handlebars::Handlebars; +use hyper::Method; +use hyper::StatusCode; +use hyper::{Body, Request, Response}; +use serde::{Deserialize, Serialize}; +use std::convert::Infallible; // TODO: + +pub async fn router( + req: Request<Body>, + _client: mongodb::Client, +) -> Result<Response<Body>, Infallible> { + match (req.method(), req.uri().path()) { + (&Method::GET, "/") | (&Method::GET, "/index.html") => Ok(Response::new("Welcome!".into())), + (&Method::GET, "/parts") | (&Method::GET, "/parts/index.html") => get_parts(req).await, + _ => Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body("Not found.".into()) + .unwrap()), + } +} + +async fn get_parts(req: Request<Body>) -> Result<Response<Body>, Infallible> { + let query = req.uri().query().unwrap_or_default(); + let filter = serde_urlencoded::de::from_str::<PartsQuery>(query).unwrap(); + let mut reg = Handlebars::new(); + reg.register_template_string("index", templates::INDEX_T) + .unwrap(); + let mut data = PartsData::default(); + data.makes = Some(vec!["Hudson".into(), "Essex".into(), "Terraplane".into()]); + + if let Some(make) = filter.make { + if make.eq("Hudson") { + data.models = Some(vec!["Hornet".into(), "Wasp".into(), "Jet".into()]); + } else if make.eq("Essex") { + data.models = Some(vec!["Super Six".into()]); + } + data.selected_make = Some(make); + } + + data.parts = Some(Vec::new()); + if let Some(model) = filter.model { + data.parts = Some(vec!["1".into(), "2".into(), "3".into()]); + data.selected_model = Some(model); + } + + let result = reg.render("index", &data).unwrap(); + Ok(Response::new(result.into())) +} + +#[derive(Debug, Deserialize)] +struct PartsQuery { + make: Option<String>, + year: Option<String>, + model: Option<String>, + engine: Option<String>, +} + +#[derive(Debug, Serialize, Default)] +struct PartsData { + makes: Option<Vec<String>>, + years: Option<Vec<String>>, + models: Option<Vec<String>>, + engines: Option<Vec<String>>, + selected_make: Option<String>, + selected_year: Option<String>, + selected_model: Option<String>, + selected_engine: Option<String>, + parts: Option<Vec<String>>, +} diff --git a/src/main.rs b/src/main.rs index b71df18..a2af455 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,11 @@ -use handlebars::Handlebars; -use hyper::service::{make_service_fn, service_fn}; -use hyper::Method; -use hyper::StatusCode; -use hyper::{Body, Request, Response, Server}; -use serde::{Deserialize, Serialize}; -use std::convert::Infallible; +use hyper::{ + service::{make_service_fn, service_fn}, + Server, +}; +use std::convert::Infallible; // TODO: mod config; +mod handlers; mod models; mod templates; @@ -19,7 +18,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { let make_svc = make_service_fn(move |_conn| { let client = client.clone(); - async { Ok::<_, Infallible>(service_fn(move |req| router(req, client.to_owned()))) } + async { + Ok::<_, Infallible>(service_fn(move |req| { + handlers::router(req, client.to_owned()) + })) + } }); let server = Server::bind(&addr).serve(make_svc); @@ -33,72 +36,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> { Ok(()) } -async fn router( - req: Request<Body>, - _client: mongodb::Client, -) -> Result<Response<Body>, Infallible> { - match (req.method(), req.uri().path()) { - (&Method::GET, "/") | (&Method::GET, "/index.html") => Ok(Response::new("Welcome!".into())), - (&Method::GET, "/parts") | (&Method::GET, "/parts/index.html") => get_parts(req).await, - _ => Ok(Response::builder() - .status(StatusCode::NOT_FOUND) - .body("Not found.".into()) - .unwrap()), - } -} - -async fn get_parts(req: Request<Body>) -> Result<Response<Body>, Infallible> { - let query = req.uri().query().unwrap_or_default(); - let filter = serde_urlencoded::de::from_str::<PartsQuery>(query).unwrap(); - let mut reg = Handlebars::new(); - reg.register_template_string("index", templates::INDEX_T) - .unwrap(); - let mut data = PartsData::default(); - data.makes = Some(vec!["Hudson".into(), "Essex".into(), "Terraplane".into()]); - - if let Some(make) = filter.make { - if make.eq("Hudson") { - data.models = Some(vec!["Hornet".into(), "Wasp".into(), "Jet".into()]); - } else if make.eq("Essex") { - data.models = Some(vec!["Super Six".into()]); - } - data.selected_make = Some(make); - } - - data.parts = Some(Vec::new()); - if let Some(model) = filter.model { - data.parts = Some(vec!["1".into(), "2".into(), "3".into()]); - data.selected_model = Some(model); - } - - let result = reg.render("index", &data).unwrap(); - Ok(Response::new(result.into())) -} - async fn shutdown_signal() { // Wait for CTRL+C tokio::signal::ctrl_c() .await .expect("failed to install CTRL+C signal handler"); } - -#[derive(Debug, Deserialize)] -struct PartsQuery { - make: Option<String>, - year: Option<String>, - model: Option<String>, - engine: Option<String>, -} - -#[derive(Debug, Serialize, Default)] -struct PartsData { - makes: Option<Vec<String>>, - years: Option<Vec<String>>, - models: Option<Vec<String>>, - engines: Option<Vec<String>>, - selected_make: Option<String>, - selected_year: Option<String>, - selected_model: Option<String>, - selected_engine: Option<String>, - parts: Option<Vec<String>>, -} diff --git a/src/models/mod.rs b/src/models/mod.rs index d7ff47a..1a4d1df 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] pub struct Car { - year: u16, // Yes, in 30767 years I will address this. + year: u16, // I'll worry about this in 65534 AD. make: String, model: String, engine: Engine, |