use std::path::PathBuf; use anyhow::Result; use clap::Parser; use crossterm::{ event::{DisableMouseCapture, EnableMouseCapture}, execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, }; use log::Level as RLevel; use ratatui::prelude::*; pub mod cargo; pub mod compiler; mod logger; mod test; pub mod ui; #[derive(Parser)] /// Kewl cargo addon for dashboards struct Args { #[arg(short = 'C')] /// Change to DIRECTORY before doing anything directory: Option, #[arg(short = 'l')] /// Log to LOG_FILE log_file: Option, #[arg(default_value = "trace", long = "level")] log_level: Level, } #[repr(usize)] #[derive(clap::ValueEnum, Clone, Copy)] enum Level { Error = 1, Warn, Info, Debug, Trace, } impl From for RLevel { fn from(value: Level) -> Self { // SAFETY: same unsafe { std::mem::transmute(value) } } } macro_rules! ctext { ($fmt:literal $(, $arg:expr)* $(,)?) => { ::into_text(&comat::cformat!($fmt $(, $arg)*)).expect("WHAT") }; } use ctext; fn main() -> Result<()> { let args = if std::env::args().next().unwrap().contains(".cargo/bin") { Args::parse_from(std::env::args().skip(1)) } else { Args::parse() }; if let Some(log) = args.log_file { logger::Logger::init(args.log_level.into(), log); } log::info!("startup"); let mut stdout = std::io::stdout(); let meta = cargo::meta( args.directory .as_deref() .unwrap_or(&std::env::current_dir()?), )?; enable_raw_mode()?; execute!(stdout, EnableMouseCapture, EnterAlternateScreen)?; let backend = CrosstermBackend::new(stdout); let mut terminal = Terminal::new(backend)?; let h = std::panic::take_hook(); std::panic::set_hook(Box::new(move |panic| { disable_raw_mode().unwrap(); execute!(std::io::stdout(), DisableMouseCapture, LeaveAlternateScreen).unwrap(); h(panic); })); let res = test::run(&mut terminal, args.directory.as_deref(), &meta); disable_raw_mode()?; execute!( terminal.backend_mut(), DisableMouseCapture, LeaveAlternateScreen )?; terminal.show_cursor()?; res }