1
0

Improve CLI

This commit is contained in:
Jeff 2024-12-01 23:20:27 -05:00
parent 299610e16f
commit 85e1b5cff2

View File

@ -12,7 +12,6 @@ use log::{Level, LevelFilter};
version = env!("CARGO_PKG_VERSION"), version = env!("CARGO_PKG_VERSION"),
author = env!("CARGO_PKG_AUTHORS"), author = env!("CARGO_PKG_AUTHORS"),
about = env!("CARGO_PKG_DESCRIPTION"), about = env!("CARGO_PKG_DESCRIPTION"),
)] )]
#[command(args_conflicts_with_subcommands = true)] #[command(args_conflicts_with_subcommands = true)]
struct Cli { struct Cli {
@ -62,50 +61,52 @@ enum CliMode {
#[derive(Args, Clone)] #[derive(Args, Clone)]
struct GlobalArguments { struct GlobalArguments {
/// Log level, overrides the DUST_LOG environment variable /// Log level, overrides the DUST_LOG environment variable
///
/// Possible values: trace, debug, info, warn, error
#[arg(short, long, value_name = "LOG_LEVEL")] #[arg(short, long, value_name = "LOG_LEVEL")]
log: Option<LevelFilter>, log: Option<LevelFilter>,
/// Source code sent via command line /// Source code
#[arg(short, long, value_name = "SOURCE", conflicts_with = "path")] ///
/// Conflicts with the file argument
#[arg(short, long, value_name = "SOURCE", conflicts_with = "file")]
command: Option<String>, command: Option<String>,
/// File to read source code from /// Path to a source code file
#[arg(required_unless_present = "command")] #[arg(required_unless_present = "command")]
path: Option<PathBuf>, file: Option<PathBuf>,
} }
impl GlobalArguments { fn set_log_and_get_source(arguments: GlobalArguments, start_time: Instant) -> String {
fn set_log_and_get_source(self, start_time: Instant) -> String { let GlobalArguments { command, file, log } = arguments;
let GlobalArguments { command, path, log } = self; let mut logger = env_logger::builder();
let mut logger = env_logger::builder();
logger.format(move |buf, record| { logger.format(move |buf, record| {
let elapsed = format!("T+{:.04}", start_time.elapsed().as_secs_f32()).dimmed(); let elapsed = format!("T+{:.04}", start_time.elapsed().as_secs_f32()).dimmed();
let level_display = match record.level() { let level_display = match record.level() {
Level::Info => "INFO".bold().white(), Level::Info => "INFO".bold().white(),
Level::Debug => "DEBUG".bold().blue(), Level::Debug => "DEBUG".bold().blue(),
Level::Warn => "WARN".bold().yellow(), Level::Warn => "WARN".bold().yellow(),
Level::Error => "ERROR".bold().red(), Level::Error => "ERROR".bold().red(),
Level::Trace => "TRACE".bold().purple(), Level::Trace => "TRACE".bold().purple(),
}; };
let display = format!("[{elapsed}] {level_display:5} {args}", args = record.args()); let display = format!("[{elapsed}] {level_display:5} {args}", args = record.args());
writeln!(buf, "{display}") writeln!(buf, "{display}")
}); });
if let Some(level) = log { if let Some(level) = log {
logger.filter_level(level).init(); logger.filter_level(level).init();
} else { } else {
logger.parse_env("DUST_LOG").init(); logger.parse_env("DUST_LOG").init();
} }
if let Some(source) = command { if let Some(source) = command {
source source
} else { } else {
let path = path.expect("Path is required when command is not provided"); let path = file.expect("Path is required when command is not provided");
read_to_string(path).expect("Failed to read file") read_to_string(path).expect("Failed to read file")
}
} }
} }
@ -125,7 +126,7 @@ fn main() {
no_output, no_output,
} = mode } = mode
{ {
let source = global_arguments.set_log_and_get_source(start_time); let source = set_log_and_get_source(global_arguments, start_time);
let run_result = run(&source); let run_result = run(&source);
match run_result { match run_result {
@ -148,7 +149,7 @@ fn main() {
style, style,
} = mode } = mode
{ {
let source = global_arguments.set_log_and_get_source(start_time); let source = set_log_and_get_source(global_arguments, start_time);
let chunk = match compile(&source) { let chunk = match compile(&source) {
Ok(chunk) => chunk, Ok(chunk) => chunk,
Err(error) => { Err(error) => {
@ -169,7 +170,7 @@ fn main() {
style, style,
} = mode } = mode
{ {
let source = global_arguments.set_log_and_get_source(start_time); let source = set_log_and_get_source(global_arguments, start_time);
let tokens = match lex(&source) { let tokens = match lex(&source) {
Ok(tokens) => tokens, Ok(tokens) => tokens,
Err(error) => { Err(error) => {