use clap::Parser;
use crossterm::style::Stylize;
use rsnip::cli::args::Cli;
use rsnip::cli::commands::execute_command;
use rsnip::infrastructure::complete::generate_completion_script;
use rsnip::config::{Settings, SnippetTypeConfig};
use tracing::level_filters::LevelFilter;
use tracing_subscriber::filter::filter_fn;
use tracing_subscriber::fmt::format::FmtSpan;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{fmt, Layer};
fn main() {
let cli = Cli::parse();
setup_logging(cli.debug);
if cli.generate_config {
println!("{}", include_str!("default_config.toml"));
return;
}
let config = match Settings::new() {
Ok(config) => config,
Err(e) => {
eprintln!("{}", format!("Error loading configuration: {}", e).red());
std::process::exit(1);
}
};
if let Some(shell) = cli.generator {
if let Err(e) = generate_completion_script(shell, std::io::stdout(), &config) {
eprintln!(
"{}",
format!("Error generating completion script: {}", e).red()
);
std::process::exit(1);
}
return;
}
if cli.info {
use clap::CommandFactory; if let Some(a) = Cli::command().get_author() {
println!("AUTHOR: {}", a)
}
if let Some(v) = Cli::command().get_version() {
println!("VERSION: {}", v);
}
match &config.active_config_path {
Some(path) => println!("CONFIG: {}", path.display()),
None => println!("CONFIG: Using default embedded configuration"),
}
println!("\nAvailable snippet types:");
for (name, cfg) in &config.snippet_types {
match cfg {
SnippetTypeConfig::Concrete { description, .. }
| SnippetTypeConfig::Combined { description, .. } => {
if let Some(desc) = description {
println!(" {}: {}", name, desc);
} else {
println!(" {}", name);
}
}
}
}
}
if let Err(e) = execute_command(&cli, &config) {
eprintln!("{}", format!("Error: {}", e).red());
std::process::exit(1);
}
}
fn setup_logging(verbosity: u8) {
tracing::debug!("INIT: Attempting logger init from main.rs");
let filter = match verbosity {
0 => LevelFilter::WARN,
1 => LevelFilter::INFO,
2 => LevelFilter::DEBUG,
3 => LevelFilter::TRACE,
_ => {
eprintln!("Don't be crazy, max is -d -d -d");
LevelFilter::TRACE
}
};
let noisy_modules = ["x"];
let module_filter = filter_fn(move |metadata| {
!noisy_modules
.iter()
.any(|name| metadata.target().starts_with(name))
});
let fmt_layer = fmt::layer()
.with_writer(std::io::stderr) .with_target(true)
.with_thread_names(false)
.with_span_events(FmtSpan::ENTER)
.with_span_events(FmtSpan::CLOSE);
let filtered_layer = fmt_layer.with_filter(filter).with_filter(module_filter);
tracing_subscriber::registry().with(filtered_layer).init();
match filter {
LevelFilter::INFO => tracing::info!("Debug mode: info"),
LevelFilter::DEBUG => tracing::debug!("Debug mode: debug"),
LevelFilter::TRACE => tracing::debug!("Debug mode: trace"),
_ => {}
}
}
#[cfg(test)]
mod tests {
use super::*;
use tracing::info;
#[test]
fn verify_cli() {
use clap::CommandFactory;
Cli::command().debug_assert();
info!("CLI verified");
}
}