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:
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -339,6 +339,18 @@ version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
|
||||
[[package]]
|
||||
name = "enum_dispatch"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
@ -494,6 +506,7 @@ dependencies = [
|
||||
"crossterm",
|
||||
"csv",
|
||||
"dirs",
|
||||
"enum_dispatch",
|
||||
"flate2",
|
||||
"indexmap",
|
||||
"proptest",
|
||||
|
||||
@ -23,6 +23,7 @@ unicode-width = "0.2"
|
||||
dirs = "5"
|
||||
csv = "1"
|
||||
clap = { version = "4.6.0", features = ["derive"] }
|
||||
enum_dispatch = "0.3.13"
|
||||
|
||||
[dev-dependencies]
|
||||
proptest = "1"
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
pkgs.pkg-config
|
||||
pkgs.rust-analyzer
|
||||
crate2nix.packages.${system}.default
|
||||
pkgs.cargo-expand
|
||||
];
|
||||
RUST_BACKTRACE = "1";
|
||||
};
|
||||
|
||||
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