use crate::{config::CONFIG_INSTANCE, error::TwinHError}; use hyper::{ service::{make_service_fn, service_fn}, Server, }; use std::env; mod config; mod error; mod import; mod models; mod repo; mod routes; mod templates; #[tokio::main] async fn main() -> Result<(), Box> { // handle non-config args for arg in env::args().skip(1) { match arg.as_str() { "--create-db" => { // create a fresh database and quit repo::create_new_db()?; return Ok(()); } "--import" => { // import CSV data into database todo!(); } "--help" | "-h" => { // print help print!( "twinh: a home-grown classic car parts catalog\n\ \nUsage: twinh [options]\n\ your database directory (e.g. /var/db/twinh)\n\ \nOptions:\n\ --help | -h prints this message and exits\n\ --addr an ip address to bind to (e.g. 127.0.0.1)\n\ --port a port to bind to (e.g. 5353)\n\ --create-db creates a fresh empty database; cannot exist yet\n\ --import-cars imports CSV car data into the database\n\ --import-parts imports CSV parts data into the database\n\ " ); return Ok(()); } unknown => { panic!("unknown option: {}", unknown); } }; } // gather config let bind_addr = CONFIG_INSTANCE.bind_addr; // create primary listener let make_svc = make_service_fn(move |_conn| async { Ok::<_, TwinHError>(service_fn(routes::router)) }); // bind server let server = Server::bind(&bind_addr).serve(make_svc); let graceful = server.with_graceful_shutdown(shutdown_signal()); // start and run until signal if let Err(e) = graceful.await { eprintln!("server error: {}", e); } Ok(()) } async fn shutdown_signal() { // Wait for CTRL+C tokio::signal::ctrl_c() .await .expect("failed to install CTRL+C signal handler"); }