blob: 02fdc2e59e2a47cae26543f757c1261924ace47c (
plain) (
tree)
|
|
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<dyn std::error::Error>> {
// 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 <dir> [options]\n\
<dir> 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; <dir> 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");
}
|