From 0c63ae51d1221b8ecd9742c7d5580bd06551ecbb Mon Sep 17 00:00:00 2001 From: "Adam T. Carpenter" Date: Thu, 4 Mar 2021 18:14:12 -0500 Subject: did some templating, added some models --- .gitignore | 2 ++ Cargo.toml | 4 ++- artifacts/categories | 48 +++++++++++++++++++++++++ artifacts/makes-models | 5 +++ artifacts/template.json | 22 ++++++++++++ src/config.rs | 22 ++++++++++++ src/main.rs | 43 +++++++++++++++------- src/models/mod.rs | 43 ++++++++++++++++++++++ src/templates/index.html | 92 ++++++++++++++++++++++++++++++++++++------------ 9 files changed, 245 insertions(+), 36 deletions(-) create mode 100644 artifacts/categories create mode 100644 artifacts/makes-models create mode 100644 artifacts/template.json create mode 100644 src/config.rs create mode 100644 src/models/mod.rs diff --git a/.gitignore b/.gitignore index 422814a..f504fd3 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ Cargo.lock #Added by cargo /target + +.env diff --git a/Cargo.toml b/Cargo.toml index f3608d2..4fc3f0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,12 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +env_logger = "0.8" handlebars = "3.5" hyper = { version = "0.14", default-features = false, features = ["full"] } +log = "0.4" mongodb = "1.2" -once_cell = "1.5" +once_cell = "1.7" serde = "1.0" serde_json = "1.0" serde_urlencoded = "0.7" diff --git a/artifacts/categories b/artifacts/categories new file mode 100644 index 0000000..4f9ad46 --- /dev/null +++ b/artifacts/categories @@ -0,0 +1,48 @@ +From [Wikipedia](https://en.wikipedia.org/wiki/List_of_auto_parts). Could be adapted for use in this application. Need to dump electronic parts that aren't as important and add parts that are no longer considered essential equipment. + +1 Car body and main part + + 1.1 Body components, including trim + 1.2 Doors + 1.3 Windows + +2 Low voltage/auxiliary electrical system and electronics + + 2.1 Audio/video devices + 2.2 Cameras + 2.3 Low voltage electrical supply system + 2.4 Gauges and meters + 2.5 Ignition system + 2.6 Lighting and signaling system + 2.7 Sensors + 2.8 Starting system + 2.9 Electrical switches + 2.10 Wiring harnesses + 2.11 Miscellaneous + +3 Interior + + 3.1 Floor components and parts + 3.2 Other components + 3.3 Car seat + +4 Power-train and chassis + + 4.1 Braking system + 4.2 Electrified powertrain components + 4.3 Engine components and parts + 4.4 Engine cooling system + 4.5 Engine oil systems + 4.6 Exhaust system + 4.7 Fuel supply system + 4.8 Suspension and steering systems + 4.9 Transmission system + +5 Miscellaneous auto parts + + 5.1 Air conditioning system (A/C) + 5.2 Bearings + 5.3 Hose + 5.4 Other miscellaneous parts + + diff --git a/artifacts/makes-models b/artifacts/makes-models new file mode 100644 index 0000000..a18b407 --- /dev/null +++ b/artifacts/makes-models @@ -0,0 +1,5 @@ +Hudson + Hornet + Wasp + Pacemaker + diff --git a/artifacts/template.json b/artifacts/template.json new file mode 100644 index 0000000..ddacc2a --- /dev/null +++ b/artifacts/template.json @@ -0,0 +1,22 @@ +{ + "type": "part", + "shortName": "Wheel Bearing", + "fitsCars": [ + { + "type": "car", + "year": 1953, + "make": "Hudson", + "model": "Hornet", + "engine": { + "type": "engine", + "cylinders": 6, + "displacement": 308, + "layout": "I" + }, + "doors": 4, + "transmission": "Dual-Range Hydramatic" + } + ], + "sources": ["url://", "url://"], + "categories": ["Wheel & Tire", "Drivetrain"] +} diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..7798967 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,22 @@ +use once_cell::sync::Lazy; +use std::{env::var, error::Error, net::SocketAddr}; + +pub static INSTANCE: Lazy = + Lazy::new(|| AppConfig::from_env().expect("Error loading config")); + +#[derive(Clone, Debug)] +pub struct AppConfig { + pub addr: SocketAddr, + pub db_uri: String, +} + +impl AppConfig { + pub fn from_env() -> Result> { + let new = Self { + addr: var("TWINH_ADDR")?.parse()?, + db_uri: var("TWINH_DB_URI")?, + }; + + Ok(new) + } +} diff --git a/src/main.rs b/src/main.rs index 2f5bdf4..b71df18 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,16 +5,22 @@ use hyper::StatusCode; use hyper::{Body, Request, Response, Server}; use serde::{Deserialize, Serialize}; use std::convert::Infallible; -use std::net::SocketAddr; +mod config; +mod models; mod templates; #[tokio::main] -async fn main() { - // bind to 127.0.0.1:3000 - let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); +async fn main() -> Result<(), Box> { + let addr = config::INSTANCE.addr; - let make_svc = make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(router)) }); + let client = mongodb::Client::with_uri_str(&config::INSTANCE.db_uri).await?; + + let make_svc = make_service_fn(move |_conn| { + let client = client.clone(); + + async { Ok::<_, Infallible>(service_fn(move |req| router(req, client.to_owned()))) } + }); let server = Server::bind(&addr).serve(make_svc); let graceful = server.with_graceful_shutdown(shutdown_signal()); @@ -23,12 +29,17 @@ async fn main() { if let Err(e) = graceful.await { eprintln!("server error: {}", e); } + + Ok(()) } -async fn router(req: Request) -> Result, Infallible> { +async fn router( + req: Request, + _client: mongodb::Client, +) -> Result, 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, + (&Method::GET, "/parts") | (&Method::GET, "/parts/index.html") => get_parts(req).await, _ => Ok(Response::builder() .status(StatusCode::NOT_FOUND) .body("Not found.".into()) @@ -36,14 +47,14 @@ async fn router(req: Request) -> Result, Infallible> { } } -async fn parts(req: Request) -> Result, Infallible> { +async fn get_parts(req: Request) -> Result, Infallible> { let query = req.uri().query().unwrap_or_default(); - let filter = serde_urlencoded::de::from_str::(query).unwrap(); + let filter = serde_urlencoded::de::from_str::(query).unwrap(); 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()]); + 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") { @@ -72,16 +83,22 @@ async fn shutdown_signal() { } #[derive(Debug, Deserialize)] -struct PartsRequest { +struct PartsQuery { make: Option, + year: Option, model: Option, + engine: Option, } #[derive(Debug, Serialize, Default)] -struct PartsView { +struct PartsData { makes: Option>, + years: Option>, models: Option>, + engines: Option>, selected_make: Option, + selected_year: Option, selected_model: Option, + selected_engine: Option, parts: Option>, } diff --git a/src/models/mod.rs b/src/models/mod.rs new file mode 100644 index 0000000..d7ff47a --- /dev/null +++ b/src/models/mod.rs @@ -0,0 +1,43 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +pub struct Car { + year: u16, // Yes, in 30767 years I will address this. + make: String, + model: String, + engine: Engine, + doors: u8, + transmission: Transmission, +} + +#[derive(Serialize, Deserialize)] +pub struct Part { + name: String, + compatible_cars: Vec, + sources: Vec, + categories: Vec, +} + +#[derive(Serialize, Deserialize)] +pub enum Source { + Uri(String), +} + +#[derive(Serialize, Deserialize)] +pub struct Engine { + cylinders: u8, + displacement: u16, + layout: Layout, +} + +#[derive(Serialize, Deserialize)] +pub enum Layout { + I, + V, +} + +#[derive(Serialize, Deserialize)] +pub struct Transmission(String); + +#[derive(Serialize, Deserialize)] +pub struct Category(String); diff --git a/src/templates/index.html b/src/templates/index.html index 683891c..4663f5d 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -4,34 +4,82 @@ -

Parts Catalog

- {{#each makes}} -
- {{#if (eq this ../selected_make)}} - - - {{#each ../models}} - {{#if (eq this ../../selected_model)}} - - Parts for {{ this }} - {{else}} - - {{/if}} +
+ +
+
+ + + + +
+ + {{#each parts}} + + + + {{/each}} +
{{ this }}
+
-- cgit v1.2.3