use crate::error::TwinHError; use hyper::{ service::{make_service_fn, service_fn}, Server, }; use std::{env, net::IpAddr, net::Ipv4Addr, net::SocketAddr}; mod error; mod import; mod models; mod repo; mod routes; mod templates; #[tokio::main] async fn main() -> Result<(), TwinHError> { // print help if there are no arguments let mut args = env::args().skip(1).peekable(); if args.peek().is_none() { print_help(); return Ok(()); } // set default bind addr let mut bind_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 5353); // handle arguments and options while let Some(arg) = args.next() { match arg.as_str() { "--create-db" => { // create a fresh database and quit repo::create_new_db()?; return Ok(()); } "--import" => { // import CSV data into database let _source = args .next() .ok_or_else(|| TwinHError(String::from("import source not provided")))?; todo!(); } "--addr" => { bind_addr.set_ip(args.next().unwrap_or_default().parse()?); } "--port" => { bind_addr.set_port(args.next().unwrap_or_default().parse()?); } _ => { // if not the last argument (the database) then it's unknown if args.peek().is_some() { print_help(); return Ok(()); } } }; } // 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 graceful.await?; Ok(()) } async fn shutdown_signal() { // Wait for CTRL+C tokio::signal::ctrl_c() .await .expect("failed to install CTRL+C signal handler"); } fn 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\ --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\ " ); }