summaryrefslogtreecommitdiffstats
path: root/src/cli.rs
diff options
context:
space:
mode:
authorToby Vincent <tobyv13@gmail.com>2022-11-01 13:00:07 -0500
committerToby Vincent <tobyv13@gmail.com>2022-11-01 13:02:02 -0500
commit698d811059ebb6787305e8293a77837323fc9311 (patch)
tree218818bf54373848d49ec3e888e9d8c51bace845 /src/cli.rs
parent61e7c46e5b805c2fda1b4724fb8389a187c75987 (diff)
feat: impl cli, config, and logging
via clap, figment, and tracing, respectively
Diffstat (limited to 'src/cli.rs')
-rw-r--r--src/cli.rs81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/cli.rs b/src/cli.rs
new file mode 100644
index 0000000..5da1036
--- /dev/null
+++ b/src/cli.rs
@@ -0,0 +1,81 @@
+use crate::{Config, Result};
+use clap::{Args, Parser};
+use std::fs::File;
+use std::sync::Arc;
+use tracing_subscriber::{filter::LevelFilter, Layer, Registry};
+
+/// Simple program to manage projects and ssh hosts using tmux
+#[derive(Parser, Debug)]
+#[command(author, version, about)]
+pub struct Cli {
+ #[command(flatten)]
+ pub verbose: Verbosity,
+
+ /// Connect to ssh host
+ #[arg(short, long)]
+ pub ssh: Option<String>,
+
+ #[command(flatten)]
+ pub config: Config,
+}
+
+impl Cli {
+ pub fn as_layer(&self) -> Result<Vec<Box<dyn Layer<Registry> + Send + Sync>>> {
+ let mut layers = Vec::new();
+
+ let fmt_layer = tracing_subscriber::fmt::layer()
+ .pretty()
+ .with_filter(self.verbose.into_filter())
+ .boxed();
+
+ layers.push(fmt_layer);
+
+ if self.config.enable_logging {
+ let file = File::create(&self.config.log_file)?;
+ let log_layer = tracing_subscriber::fmt::layer()
+ .with_writer(Arc::new(file))
+ .boxed();
+ layers.push(log_layer);
+ };
+
+ Ok(layers)
+ }
+}
+
+#[derive(Debug, Default, Args)]
+pub struct Verbosity {
+ /// Print additional information per occurrence
+ #[arg(short, long, action = clap::ArgAction::Count, conflicts_with = "quiet")]
+ pub verbose: u8,
+
+ /// Suppress all output
+ #[arg(short, long, global = true, conflicts_with = "verbose")]
+ pub quiet: bool,
+}
+
+impl Verbosity {
+ pub fn into_filter(&self) -> LevelFilter {
+ self.into()
+ }
+}
+
+impl From<&Verbosity> for LevelFilter {
+ fn from(value: &Verbosity) -> Self {
+ match value.verbose + 1 - u8::from(value.quiet) {
+ 0 => LevelFilter::OFF,
+ 1 => LevelFilter::ERROR,
+ 2 => LevelFilter::WARN,
+ 3 => LevelFilter::INFO,
+ 4 => LevelFilter::DEBUG,
+ _ => LevelFilter::TRACE,
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn test_start() {
+ assert_eq!(1, 1);
+ }
+}