diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 77 | ||||
-rw-r--r-- | src/templates/index.html | 38 | ||||
-rw-r--r-- | src/templates/mod.rs | 1 |
3 files changed, 97 insertions, 19 deletions
diff --git a/src/main.rs b/src/main.rs index 9d4a4f4..6947482 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,39 +1,88 @@ +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 std::net::SocketAddr; +mod templates; + #[tokio::main] async fn main() { - // We'll bind to 127.0.0.1:3000 + // bind to 127.0.0.1:3000 let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); - // A `Service` is needed for every connection, so this - // creates one from our `hello_world` function. - let make_svc = make_service_fn(|_conn| async { - // service_fn converts our function into a `Service` - Ok::<_, Infallible>(service_fn(hello_world)) - }); + let make_svc = make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(router)) }); - // And construct the `Server` like normal... let server = Server::bind(&addr).serve(make_svc); - - // And now add a graceful shutdown signal... let graceful = server.with_graceful_shutdown(shutdown_signal()); - // Run this server for... forever! + // run until shutdown signal if let Err(e) = graceful.await { eprintln!("server error: {}", e); } } -async fn hello_world(_req: Request<Body>) -> Result<Response<Body>, Infallible> { - Ok(Response::new("Hello, World".into())) +async fn router(req: Request<Body>) -> 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") => parts(req).await, + _ => Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body("Not found.".into()) + .unwrap()), + } +} + +async fn parts(req: Request<Body>) -> Result<Response<Body>, Infallible> { + let query = req.uri().query().unwrap_or_default(); + let filter = serde_urlencoded::de::from_str::<PartsRequest>(query).unwrap(); + dbg!(&query, &filter); + let mut reg = Handlebars::new(); + reg.register_template_string("index", templates::INDEX_T) + .unwrap(); + let mut data = PartsView::default(); + data.makes = Some(vec!["Hudson".into(), "Essex".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 the CTRL+C signal + // Wait for CTRL+C tokio::signal::ctrl_c() .await .expect("failed to install CTRL+C signal handler"); } + +#[derive(Debug, Deserialize)] +struct PartsRequest { + make: Option<String>, + model: Option<String>, +} + +#[derive(Debug, Serialize, Default)] +struct PartsView { + makes: Option<Vec<String>>, + models: Option<Vec<String>>, + selected_make: Option<String>, + selected_model: Option<String>, + parts: Option<Vec<String>>, +} diff --git a/src/templates/index.html b/src/templates/index.html index 7b6070c..6b2f54a 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -1,10 +1,38 @@ <!DOCTYPE html> <html> + <head> + <meta charset="UTF-8" /> + + <style> + input[type="submit"] { + display: block; + } + </style> + </head> <body> - <ul> - <li>Essex</li> - <li>Hudson</li> - <li>Terraplane</li> - </ul> + <h1>Parts Catalog</h1> + <form action="/parts"> + <ul> + {{#each makes}} + <li> + <input type="submit" name="make" value="{{ this }}" /> + {{#if (eq this "Hudson")}} + <ul> + <input type="hidden" name="make" value="{{ selected_make }}" /> + {{#each models}} + <li> + <input type="submit" name="model" value="{{ this }}" /> + </li> + {{else}} + No models found. + {{/each}} + </ul> + {{/if}} + </li> + {{else}} + No makes found. + {{/each}} + </ul> + </form> </body> </html> diff --git a/src/templates/mod.rs b/src/templates/mod.rs new file mode 100644 index 0000000..1a594fb --- /dev/null +++ b/src/templates/mod.rs @@ -0,0 +1 @@ +pub static INDEX_T: &str = include_str!("index.html"); |