hkxc/args/
convert.rs

1//! Convert hkx <-> xml
2use super::progress_handler::CliProgressHandler;
3use clap::ValueEnum;
4use serde_hkx_features::{convert::OutFormat, error::Result};
5use std::path::{Path, PathBuf};
6
7/// ANSI color representation command examples.
8pub const EXAMPLES: &str = color_print::cstr!(
9    r#"<blue><bold><underline>Examples</underline></bold></blue>
10- <blue!>hkx -> xml</blue!>
11  <cyan!>hkxc convert --input</cyan!> ./defaultmale.hkx <cyan!>--format</cyan!> xml
12
13- <blue!>xml -> hkx(64bit)</blue!>
14  <cyan!>hkxc convert -i</cyan!> ./defaultmale.xml <cyan!>-v</cyan!> amd64 <cyan!>--stdout --log-level</cyan!> trace
15
16- <blue!>hkx(32bit) -> hkx(64bit)</blue!>
17  <cyan!>hkxc convert -i</cyan!> ./defaultmale_x86.hkx <cyan!>-o</cyan!> ./defaultmale_x64.hkx <cyan!>-v</cyan!> amd64 <cyan!>--log-level</cyan!> debug <cyan!>--log-file</cyan!> "./convert_x86_to_x64_bytes.log"
18
19- <blue!>hkx(64bit) -> hkx(32bit)</blue!>
20  <cyan!>hkxc convert -i</cyan!> ./defaultmale_x64.hkx <cyan!>-o</cyan!> ./defaultmale_x86.hkx <cyan!>-v</cyan!> win32 <cyan!>--log-level</cyan!> trace <cyan!>--log-file</cyan!> ./convert_x64_to_x86_bytes.log
21"#
22);
23
24#[derive(Debug, clap::Args)]
25#[clap(arg_required_else_help = true, after_long_help = EXAMPLES)]
26pub(crate) struct Args {
27    /// Path containing the hkx/xml file/directory
28    #[clap(short, long)]
29    pub input: PathBuf,
30    /// Output path (If not specified, it is automatically created in the same location as the input path.)
31    #[clap(short, long)]
32    pub output: Option<PathBuf>,
33
34    /// File format to output
35    #[clap(short = 'v', long, ignore_case = true)]
36    pub format: OutFormat,
37
38    /// Execution runtime: async (Tokio) or parallel (Rayon) (NOTE: Effective only when dir path is selected.)
39    #[arg(short, long, ignore_case = true, default_value = "rayon")]
40    pub runtime: Runtime,
41}
42
43/// Runtime options
44#[derive(ValueEnum, Clone, Debug)]
45pub enum Runtime {
46    /// Uses Rayon for multi-threaded parallel processing & Enumerate error paths
47    Rayon,
48    /// Uses Tokio for async processing(M:N thread) & fail fast
49    Tokio,
50}
51
52pub async fn convert<I, O>(
53    input: I,
54    output: Option<O>,
55    format: OutFormat,
56    runtime: Runtime,
57) -> Result<()>
58where
59    I: AsRef<Path>,
60    O: AsRef<Path> + Sync,
61{
62    match runtime {
63        Runtime::Rayon => rayon_convert(&input, output, format),
64        Runtime::Tokio => tokio_convert(&input, output, format).await,
65    }
66}
67
68fn rayon_convert<I, O>(input: I, output: Option<O>, format: OutFormat) -> Result<()>
69where
70    I: AsRef<Path>,
71    O: AsRef<Path> + Sync,
72{
73    serde_hkx_features::convert::rayon::convert_progress(
74        input,
75        output,
76        format,
77        CliProgressHandler::new(),
78    )
79}
80
81/// convert with cli progress.
82pub async fn tokio_convert<I, O>(input: I, output: Option<O>, format: OutFormat) -> Result<()>
83where
84    I: AsRef<Path>,
85    O: AsRef<Path>,
86{
87    serde_hkx_features::convert::tokio::convert_progress(
88        input,
89        output,
90        format,
91        CliProgressHandler::new(),
92    )
93    .await
94}