1use super::{RunOpts, handle_run_command};
3use crate::example::patches::{get_patch_names, get_patches};
4use crate::example::{Example, get_example_names};
5use crate::patch::ModelPatch;
6use anyhow::{Context, Result};
7use clap::Subcommand;
8use std::fs;
9use std::path::{Path, PathBuf};
10use tempfile::TempDir;
11
12#[derive(Subcommand)]
14pub enum ExampleSubcommands {
15 List {
17 #[arg(long, hide = true)]
19 patch: bool,
20 },
21 Info {
23 name: String,
25 },
26 Extract {
28 name: String,
30 new_path: Option<PathBuf>,
32 #[arg(long, hide = true)]
34 patch: bool,
35 },
36 Run {
38 name: String,
40 #[arg(long, hide = true)]
42 patch: bool,
43 #[command(flatten)]
45 opts: RunOpts,
46 },
47}
48
49impl ExampleSubcommands {
50 pub fn execute(self) -> Result<()> {
52 match self {
53 Self::List { patch } => handle_example_list_command(patch),
54 Self::Info { name } => handle_example_info_command(&name)?,
55 Self::Extract {
56 name,
57 patch,
58 new_path,
59 } => handle_example_extract_command(&name, new_path.as_deref(), patch)?,
60 Self::Run { name, patch, opts } => {
61 handle_example_run_command(&name, patch, &opts)?;
62 }
63 }
64
65 Ok(())
66 }
67}
68
69fn handle_example_list_command(patch: bool) {
71 if patch {
72 for name in get_patch_names() {
73 println!("{name}");
74 }
75 } else {
76 for name in get_example_names() {
77 println!("{name}");
78 }
79 }
80}
81
82fn handle_example_info_command(name: &str) -> Result<()> {
84 let info = Example::from_name(name)?
86 .get_readme()
87 .unwrap_or_else(|_| panic!("Could not load README.txt for '{name}' example"));
88 print!("{info}");
89
90 Ok(())
91}
92
93fn handle_example_extract_command(name: &str, dest: Option<&Path>, patch: bool) -> Result<()> {
95 extract_example(name, patch, dest.unwrap_or(Path::new(name)))
96}
97
98fn extract_example(name: &str, patch: bool, dest: &Path) -> Result<()> {
102 if patch {
103 let patches = get_patches(name)?;
104
105 let example = Example::from_name("simple").unwrap();
107
108 let example_tmp = TempDir::new().context("Failed to create temporary directory")?;
110 let example_path = example_tmp.path().join(name);
111 example
112 .extract(&example_path)
113 .context("Could not extract example")?;
114
115 fs::create_dir(dest).context("Could not create output directory")?;
117 ModelPatch::new(example_path)
118 .with_file_patches(patches.to_owned())
119 .build(dest)
120 .context("Failed to patch example")
121 } else {
122 let example = Example::from_name(name)?;
124 example.extract(dest)
125 }
126}
127
128pub fn handle_example_run_command(name: &str, patch: bool, opts: &RunOpts) -> Result<()> {
130 let temp_dir = TempDir::new().context("Failed to create temporary directory")?;
131 let model_path = temp_dir.path().join(name);
132 extract_example(name, patch, &model_path)?;
133 handle_run_command(&model_path, opts)
134}