refactor: split main code paths for clarity.
This commit is contained in:
129
src/main.rs
129
src/main.rs
@ -34,22 +34,70 @@ use ui::import_wizard_ui::ImportWizardWidget;
|
||||
use ui::tile_bar::TileBar;
|
||||
use ui::view_panel::ViewPanel;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let arg_config = parse_args(args);
|
||||
arg_config.run()
|
||||
}
|
||||
|
||||
trait Runnable {
|
||||
fn run(self: Box<Self>) -> Result<()>;
|
||||
}
|
||||
|
||||
struct CmdLineArgs {
|
||||
file_path: Option<PathBuf>,
|
||||
import_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
enum ArgConfig {
|
||||
Help,
|
||||
Headless {
|
||||
file_path: Option<PathBuf>,
|
||||
commands: Vec<String>,
|
||||
script: Option<PathBuf>,
|
||||
},
|
||||
Default(CmdLineArgs),
|
||||
impl Runnable for CmdLineArgs {
|
||||
fn run(self: Box<Self>) -> Result<()> {
|
||||
// Load or create model
|
||||
let model = get_initial_model(&self.file_path)?;
|
||||
|
||||
// Pre-TUI import: parse JSON and open wizard
|
||||
let import_json = if let Some(ref path) = self.import_path {
|
||||
match std::fs::read_to_string(path) {
|
||||
Err(e) => {
|
||||
eprintln!("Cannot read '{}': {e}", path.display());
|
||||
return Ok(());
|
||||
}
|
||||
Ok(content) => match serde_json::from_str::<serde_json::Value>(&content) {
|
||||
Err(e) => {
|
||||
eprintln!("JSON parse error: {e}");
|
||||
return Ok(());
|
||||
}
|
||||
Ok(json) => Some(json),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
run_tui(model, self.file_path, import_json)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_args(args: Vec<String>) -> ArgConfig {
|
||||
struct HeadlessArgs {
|
||||
file_path: Option<PathBuf>,
|
||||
commands: Vec<String>,
|
||||
script: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl Runnable for HeadlessArgs {
|
||||
fn run(self: Box<Self>) -> Result<()> {
|
||||
run_headless(self.file_path, self.commands, self.script)
|
||||
}
|
||||
}
|
||||
|
||||
struct HelpArgs {}
|
||||
|
||||
impl Runnable for HelpArgs {
|
||||
fn run(self: Box<Self>) -> Result<()> {
|
||||
print_usage()
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_args(args: Vec<String>) -> Box<dyn Runnable> {
|
||||
let mut file_path: Option<PathBuf> = None;
|
||||
let mut headless_cmds: Vec<String> = Vec::new();
|
||||
let mut headless_script: Option<PathBuf> = None;
|
||||
@ -73,7 +121,7 @@ fn parse_args(args: Vec<String>) -> ArgConfig {
|
||||
import_path = args.get(i).map(PathBuf::from);
|
||||
}
|
||||
"--help" | "-h" => {
|
||||
return ArgConfig::Help;
|
||||
return Box::new(HelpArgs {});
|
||||
}
|
||||
arg if !arg.starts_with('-') => {
|
||||
file_path = Some(PathBuf::from(arg));
|
||||
@ -84,14 +132,14 @@ fn parse_args(args: Vec<String>) -> ArgConfig {
|
||||
}
|
||||
|
||||
if !headless_cmds.is_empty() || headless_script.is_some() {
|
||||
return ArgConfig::Headless {
|
||||
return Box::new(HeadlessArgs {
|
||||
file_path,
|
||||
commands: headless_cmds,
|
||||
script: headless_script,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return ArgConfig::Default(CmdLineArgs {
|
||||
return Box::new(CmdLineArgs {
|
||||
file_path,
|
||||
import_path,
|
||||
});
|
||||
@ -117,58 +165,12 @@ fn get_initial_model(file_path: &Option<PathBuf>) -> Result<Model> {
|
||||
};
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
|
||||
let arg_config = parse_args(args);
|
||||
|
||||
match arg_config {
|
||||
ArgConfig::Default(cmd_line_args) => {
|
||||
// Load or create model
|
||||
let model = get_initial_model(&cmd_line_args.file_path)?;
|
||||
|
||||
// Pre-TUI import: parse JSON and open wizard
|
||||
let import_json = if let Some(ref path) = cmd_line_args.import_path {
|
||||
match std::fs::read_to_string(path) {
|
||||
Err(e) => {
|
||||
eprintln!("Cannot read '{}': {e}", path.display());
|
||||
return Ok(());
|
||||
}
|
||||
Ok(content) => match serde_json::from_str::<serde_json::Value>(&content) {
|
||||
Err(e) => {
|
||||
eprintln!("JSON parse error: {e}");
|
||||
return Ok(());
|
||||
}
|
||||
Ok(json) => Some(json),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
run_tui(model, cmd_line_args.file_path, import_json)
|
||||
}
|
||||
ArgConfig::Headless {
|
||||
file_path,
|
||||
commands,
|
||||
script,
|
||||
} => {
|
||||
let mut model = get_initial_model(&file_path)?;
|
||||
return run_headless(&mut model, file_path, commands, script);
|
||||
}
|
||||
ArgConfig::Help => {
|
||||
print_usage();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run_headless(
|
||||
model: &mut Model,
|
||||
file_path: Option<PathBuf>,
|
||||
inline_cmds: Vec<String>,
|
||||
script: Option<PathBuf>,
|
||||
) -> Result<()> {
|
||||
let mut model = get_initial_model(&file_path)?;
|
||||
let mut cmds: Vec<String> = inline_cmds;
|
||||
if let Some(script_path) = script {
|
||||
let content = std::fs::read_to_string(&script_path)?;
|
||||
@ -191,7 +193,7 @@ fn run_headless(
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let result = command::dispatch(model, &parsed);
|
||||
let result = command::dispatch(&mut model, &parsed);
|
||||
if !result.ok {
|
||||
exit_code = 1;
|
||||
}
|
||||
@ -199,7 +201,7 @@ fn run_headless(
|
||||
}
|
||||
|
||||
if let Some(path) = file_path {
|
||||
persistence::save(model, &path)?;
|
||||
persistence::save(&mut model, &path)?;
|
||||
}
|
||||
|
||||
std::process::exit(exit_code);
|
||||
@ -560,7 +562,7 @@ fn draw_welcome(f: &mut Frame, area: Rect, _app: &App) {
|
||||
|
||||
// ── Usage ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
fn print_usage() {
|
||||
fn print_usage() -> Result<()> {
|
||||
println!("improvise — multi-dimensional data modeling TUI\n");
|
||||
println!("USAGE:");
|
||||
println!(" improvise [file.improv] Open or create a model");
|
||||
@ -583,4 +585,5 @@ fn print_usage() {
|
||||
println!(" F C V Toggle Formulas / Categories / Views panel");
|
||||
println!(" ZZ Save and quit");
|
||||
println!(" ? Help");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user