feat: use enum_dispatch for command dispatch and add Open command
Replace manual dynamic dispatch using Box <dyn Runnable> with enum_dispatch for improved performance and cleaner code. Add a new Open command to allow opening the TUI as the default behavior when no subcommand is provided. Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
This commit is contained in:
37
src/main.rs
37
src/main.rs
@ -14,6 +14,7 @@ use std::path::PathBuf;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use clap::{Parser, Subcommand};
|
||||
use enum_dispatch::enum_dispatch;
|
||||
|
||||
use draw::run_tui;
|
||||
use model::Model;
|
||||
@ -29,7 +30,13 @@ struct Cli {
|
||||
command: Option<Commands>,
|
||||
}
|
||||
|
||||
#[enum_dispatch]
|
||||
trait Runnable {
|
||||
fn run(self, model_file: Option<PathBuf>) -> Result<()>;
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
#[enum_dispatch(Runnable)]
|
||||
enum Commands {
|
||||
/// Import JSON or CSV data, then open TUI (or save with --output)
|
||||
Import(ImportArgs),
|
||||
@ -37,6 +44,8 @@ enum Commands {
|
||||
Cmd(CmdArgs),
|
||||
/// Run commands from a script file headless
|
||||
Script(ScriptArgs),
|
||||
/// Open the TUI (default when no subcommand given)
|
||||
Open(OpenTui),
|
||||
}
|
||||
|
||||
#[derive(clap::Args)]
|
||||
@ -105,23 +114,10 @@ struct ScriptArgs {
|
||||
file: Option<PathBuf>,
|
||||
}
|
||||
|
||||
trait Runnable {
|
||||
fn run(self: Box<Self>, model_file: Option<PathBuf>) -> Result<()>;
|
||||
}
|
||||
|
||||
impl From<Commands> for Box<dyn Runnable> {
|
||||
fn from(cmd: Commands) -> Self {
|
||||
match cmd {
|
||||
Commands::Import(args) => Box::new(args),
|
||||
Commands::Cmd(args) => Box::new(args),
|
||||
Commands::Script(args) => Box::new(args),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(clap::Args)]
|
||||
struct OpenTui;
|
||||
impl Runnable for OpenTui {
|
||||
fn run(self: Box<Self>, model_file: Option<PathBuf>) -> Result<()> {
|
||||
fn run(self, model_file: Option<PathBuf>) -> Result<()> {
|
||||
let model = get_initial_model(&model_file)?;
|
||||
run_tui(model, model_file, None)
|
||||
}
|
||||
@ -129,15 +125,12 @@ impl Runnable for OpenTui {
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let cli = Cli::parse();
|
||||
let cmd: Box<dyn Runnable> = cli
|
||||
.command
|
||||
.map(|c| -> Box<dyn Runnable> { c.into() })
|
||||
.unwrap_or_else(|| Box::new(OpenTui));
|
||||
let cmd = cli.command.unwrap_or(Commands::Open(OpenTui));
|
||||
cmd.run(cli.file)
|
||||
}
|
||||
|
||||
impl Runnable for ImportArgs {
|
||||
fn run(self: Box<Self>, model_file: Option<PathBuf>) -> Result<()> {
|
||||
fn run(self, model_file: Option<PathBuf>) -> Result<()> {
|
||||
if self.files.is_empty() {
|
||||
anyhow::bail!("No files specified for import");
|
||||
}
|
||||
@ -164,13 +157,13 @@ impl Runnable for ImportArgs {
|
||||
}
|
||||
|
||||
impl Runnable for CmdArgs {
|
||||
fn run(self: Box<Self>, _model_file: Option<PathBuf>) -> Result<()> {
|
||||
fn run(self, _model_file: Option<PathBuf>) -> Result<()> {
|
||||
run_headless_commands(&self.json, &self.file)
|
||||
}
|
||||
}
|
||||
|
||||
impl Runnable for ScriptArgs {
|
||||
fn run(self: Box<Self>, _model_file: Option<PathBuf>) -> Result<()> {
|
||||
fn run(self, _model_file: Option<PathBuf>) -> Result<()> {
|
||||
run_headless_script(&self.path, &self.file)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user