summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam T. Carpenter <atc@53hor.net>2021-04-28 19:58:27 -0400
committerAdam T. Carpenter <atc@53hor.net>2021-04-28 19:58:27 -0400
commitf206de5d49eda1900552a4b19f01c8c6985b7903 (patch)
tree86f0b681e01eeda4a8d5f03a85c988866538b981
parentd83fe68ed51016bbb87d83aa512ef8b9d3f0780e (diff)
downloadtwinh-enhancement/2.tar.xz
twinh-enhancement/2.zip
finally committed to structopt arg parsingenhancement/2
-rw-r--r--Cargo.toml8
-rw-r--r--src/config.rs48
-rw-r--r--src/error.rs4
-rw-r--r--src/main.rs72
-rw-r--r--src/repo/mod.rs27
-rw-r--r--src/routes/mod.rs4
-rw-r--r--src/templates/mod.rs29
7 files changed, 95 insertions, 97 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 13b4535..b625320 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,17 +2,19 @@
name = "twinh"
version = "0.1.0"
authors = ["Adam T. Carpenter <atc@53hor.net>"]
+description = "Twin H-Power: A classic car parts catalog and cross-reference tool"
edition = "2018"
[dependencies]
bincode = "1"
env_logger = "0.8"
handlebars = "3"
-hyper = { version = "0.14", default-features = false, features = ["full"] }
+hyper = { version = "0.14", default-features = false, features = ["server", "client", "http1", "http2"] }
hyper-rustls = "0.22"
log = "0.4"
-once_cell = "1"
+lazy_static = "1.4"
serde = { version = "1", features = ["derive"]}
serde_urlencoded = "0.7"
sled = "0.34"
-tokio = { version = "1", default-features = false, features = ["full"] }
+structopt = { version = "0.3", default-features = false }
+tokio = { version = "1", default-features = false, features = ["rt-multi-thread", "macros", "signal"] }
diff --git a/src/config.rs b/src/config.rs
new file mode 100644
index 0000000..4dd4433
--- /dev/null
+++ b/src/config.rs
@@ -0,0 +1,48 @@
+use std::{net::SocketAddrV4, path::PathBuf};
+use structopt::StructOpt;
+
+lazy_static! {
+ pub static ref INSTANCE: Config = Config::from_args();
+}
+
+#[derive(Debug, StructOpt)]
+#[structopt(author, about)]
+pub struct Config {
+ #[structopt(
+ name = "DIR",
+ required = true,
+ parse(from_str),
+ help = "The path to your data directory"
+ )]
+ pub data_dir: PathBuf,
+
+ #[structopt(
+ name = "ADDR",
+ long = "bind-addr",
+ required = false,
+ default_value = "127.0.0.1:5353",
+ help = "Sets the IP address and port to bind to"
+ )]
+ pub bind_addr: SocketAddrV4,
+
+ #[structopt(
+ long,
+ short,
+ multiple = true,
+ parse(from_occurrences),
+ help = "Increases log level"
+ )]
+ pub verbose: u8,
+
+ #[structopt(
+ long,
+ help = "Creates a fresh data directory at DIR and exits; Fails if DIR exists"
+ )]
+ pub create_dir: bool,
+
+ #[structopt(long, help = "Imports CSV car data into the data directory")]
+ pub import_cars: bool,
+
+ #[structopt(long, help = "Imports CSV parts data into the data directory")]
+ pub import_parts: bool,
+}
diff --git a/src/error.rs b/src/error.rs
index ef0ef1d..f987d66 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -8,6 +8,10 @@ use std::num::ParseIntError;
#[derive(Debug)]
pub struct TwinHError(pub String);
+impl TwinHError {
+ fn bail(self) {}
+}
+
impl std::error::Error for TwinHError {}
impl std::fmt::Display for TwinHError {
diff --git a/src/main.rs b/src/main.rs
index 0c7766a..c6a1110 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,8 +3,13 @@ use hyper::{
service::{make_service_fn, service_fn},
Server,
};
-use std::{env, net::IpAddr, net::Ipv4Addr, net::SocketAddr};
+use std::net::{IpAddr, Ipv4Addr, SocketAddr};
+use structopt::StructOpt;
+#[macro_use]
+extern crate lazy_static;
+
+mod config;
mod error;
mod import;
mod models;
@@ -14,57 +19,19 @@ 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(());
- }
- }
- };
- }
+ //env_logger::try_init_from_env;
- // create primary listener
+ // create HTTP 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);
+ // bind server with signal
+ let server = Server::bind(&config::INSTANCE.bind_addr.into()).serve(make_svc);
let graceful = server.with_graceful_shutdown(shutdown_signal());
- // start and run until signal
+ // start and run
graceful.await?;
+
Ok(())
}
@@ -74,18 +41,3 @@ async fn shutdown_signal() {
.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] <dir>\n\
- <dir> 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; <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\
- "
- );
-}
diff --git a/src/repo/mod.rs b/src/repo/mod.rs
index c7992c9..80b2814 100644
--- a/src/repo/mod.rs
+++ b/src/repo/mod.rs
@@ -1,32 +1,23 @@
+use crate::config;
use crate::error::TwinHError;
use crate::models::Car;
use crate::models::Part;
use bincode::deserialize;
use constants::*;
-use once_cell::sync::Lazy;
use sled::{Config, Db};
-use std::env;
mod constants;
-pub static DB_PATH_INSTANCE: Lazy<String> = Lazy::new(|| {
- env::args()
- .skip(1)
- .last()
- .expect("database directory not provided")
-});
-
-static REPO_INSTANCE: Lazy<Db> =
- Lazy::new(
- || match Config::default().path(DB_PATH_INSTANCE.as_str()).open() {
- Err(e) => panic!("failed to open database: {}", e),
- Ok(db) => db,
- },
- );
+lazy_static! {
+ static ref REPO_INSTANCE: Db = match Config::default().path(&config::INSTANCE.data_dir).open() {
+ Err(e) => panic!("failed to open database: {}", e),
+ Ok(db) => db,
+ };
+}
pub fn create_demo_db() -> Result<(), TwinHError> {
let db = sled::Config::default()
- .path(DB_PATH_INSTANCE.as_str())
+ .path(&config::INSTANCE.data_dir)
.create_new(true)
.open()?;
let cars_tree = db.open_tree(CARS_TREE)?;
@@ -35,7 +26,7 @@ pub fn create_demo_db() -> Result<(), TwinHError> {
pub fn create_new_db() -> Result<(), TwinHError> {
sled::Config::default()
- .path(DB_PATH_INSTANCE.as_str())
+ .path(&config::INSTANCE.data_dir)
.create_new(true)
.open()?;
Ok(())
diff --git a/src/routes/mod.rs b/src/routes/mod.rs
index 1866e49..be07aa0 100644
--- a/src/routes/mod.rs
+++ b/src/routes/mod.rs
@@ -1,5 +1,5 @@
use crate::error::TwinHError;
-use crate::repo;
+//use crate::repo;
use crate::templates;
use hyper::body::HttpBody as _;
use hyper::Method;
@@ -124,7 +124,7 @@ pub struct AccessToken {
}
async fn cars(req: Request<Body>) -> Result<Response<Body>, TwinHError> {
- let cars = repo::get_all_cars().unwrap();
+ //let cars = repo::get_all_cars().unwrap();
todo!()
}
diff --git a/src/templates/mod.rs b/src/templates/mod.rs
index 534ada0..8b8f156 100644
--- a/src/templates/mod.rs
+++ b/src/templates/mod.rs
@@ -1,16 +1,17 @@
use handlebars::Handlebars;
-use once_cell::sync::Lazy;
-pub static REGISTRY: Lazy<Handlebars> = Lazy::new(|| {
- let mut handlebars = Handlebars::new();
- handlebars
- .register_template_string("index", include_str!("index.hbs"))
- .unwrap();
- handlebars
- .register_template_string("login", include_str!("login.hbs"))
- .unwrap();
- handlebars
- .register_template_string("base", include_str!("base.hbs"))
- .unwrap();
- handlebars
-});
+lazy_static! {
+ pub static ref REGISTRY: Handlebars<'static> = {
+ let mut handlebars = Handlebars::new();
+ handlebars
+ .register_template_string("index", include_str!("index.hbs"))
+ .unwrap();
+ handlebars
+ .register_template_string("login", include_str!("login.hbs"))
+ .unwrap();
+ handlebars
+ .register_template_string("base", include_str!("base.hbs"))
+ .unwrap();
+ handlebars
+ };
+}