use super::{RunOpts, handle_run_command};
use crate::example::patches::{get_patch_names, get_patches};
use crate::example::{Example, get_example_names};
use crate::patch::ModelPatch;
use anyhow::{Context, Result};
use clap::Subcommand;
use std::fs;
use std::path::{Path, PathBuf};
use tempfile::TempDir;
#[derive(Subcommand)]
pub enum ExampleSubcommands {
List {
#[arg(long, hide = true)]
patch: bool,
},
Info {
name: String,
},
Extract {
name: String,
new_path: Option<PathBuf>,
#[arg(long, hide = true)]
patch: bool,
},
Run {
name: String,
#[arg(long, hide = true)]
patch: bool,
#[command(flatten)]
opts: RunOpts,
},
}
impl ExampleSubcommands {
pub fn execute(self) -> Result<()> {
match self {
Self::List { patch } => handle_example_list_command(patch),
Self::Info { name } => handle_example_info_command(&name)?,
Self::Extract {
name,
patch,
new_path,
} => handle_example_extract_command(&name, new_path.as_deref(), patch)?,
Self::Run { name, patch, opts } => {
handle_example_run_command(&name, patch, &opts)?;
}
}
Ok(())
}
}
fn handle_example_list_command(patch: bool) {
if patch {
for name in get_patch_names() {
println!("{name}");
}
} else {
for name in get_example_names() {
println!("{name}");
}
}
}
fn handle_example_info_command(name: &str) -> Result<()> {
let info = Example::from_name(name)?
.get_readme()
.unwrap_or_else(|_| panic!("Could not load README.txt for '{name}' example"));
print!("{info}");
Ok(())
}
fn handle_example_extract_command(name: &str, dest: Option<&Path>, patch: bool) -> Result<()> {
extract_example(name, patch, dest.unwrap_or(Path::new(name)))
}
fn extract_example(name: &str, patch: bool, dest: &Path) -> Result<()> {
if patch {
let (file_patches, toml_patch) = get_patches(name)?;
let example = Example::from_name("simple").unwrap();
let example_tmp = TempDir::new().context("Failed to create temporary directory")?;
let example_path = example_tmp.path().join(name);
example
.extract(&example_path)
.context("Could not extract example")?;
fs::create_dir(dest).context("Could not create output directory")?;
let mut model_patch =
ModelPatch::new(example_path).with_file_patches(file_patches.to_owned());
if let Some(toml_patch) = toml_patch.as_ref() {
model_patch = model_patch.with_toml_patch(toml_patch);
}
model_patch.build(dest).context("Failed to patch example")
} else {
let example = Example::from_name(name)?;
example.extract(dest)
}
}
pub fn handle_example_run_command(name: &str, patch: bool, opts: &RunOpts) -> Result<()> {
let temp_dir = TempDir::new().context("Failed to create temporary directory")?;
let model_path = temp_dir.path().join(name);
extract_example(name, patch, &model_path)?;
handle_run_command(&model_path, opts)
}