use std::str::FromStr;
use anyhow::{anyhow, Result};
use structopt::StructOpt;
#[derive(StructOpt, Debug)]
pub struct LogOptions {
#[structopt(long = "verbose", short = "v", parse(from_occurrences))]
verbosity: u8,
#[structopt(long = "log-filter", env = "ENARX_LOG")]
log_filter: Option<String>,
#[structopt(long, default_value = "stderr")]
log_target: LogTarget,
}
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
enum LogTarget {
Stdout,
Stderr,
}
impl FromStr for LogTarget {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_ascii_lowercase().as_str() {
"stdout" => Ok(Self::Stdout),
"stderr" => Ok(Self::Stderr),
_ => Err(anyhow!("unknown log target {:?}", s)),
}
}
}
impl From<LogTarget> for env_logger::Target {
fn from(t: LogTarget) -> Self {
match t {
LogTarget::Stdout => Self::Stdout,
LogTarget::Stderr => Self::Stderr,
}
}
}
impl LogOptions {
pub fn init_logger(&self) {
let mut builder = env_logger::Builder::new();
builder
.filter_level(self.verbosity_level())
.parse_filters(self.log_filter.as_ref().unwrap_or(&"".to_owned()))
.target(self.log_target.into())
.init();
}
fn verbosity_level(&self) -> log::LevelFilter {
match self.verbosity {
0 => log::LevelFilter::Error,
1 => log::LevelFilter::Warn,
2 => log::LevelFilter::Info,
3 => log::LevelFilter::Debug,
_ => log::LevelFilter::Trace,
}
}
}