1mod charts;
4mod report;
5mod runner;
6mod types;
7
8use anyhow::{Context, Result, anyhow};
9use wowlab_common::output;
10use wowlab_fs::{directory, path::PathBuf};
11use wowlab_types::game::SpecId;
12
13use crate::run::{FightDurationSeconds, IterationCount, RunParameters, RunParametersError};
14
15const DEFAULT_ITERATIONS: u32 = 100;
16const DEFAULT_DURATION: u32 = 60;
17
18#[derive(Debug, clap::Args)]
19pub(crate) struct ItemsArgs {
20 #[arg(value_name = "SPEC")]
21 pub specs: Vec<String>,
22
23 #[arg(long, short = 'n', default_value_t = DEFAULT_ITERATIONS)]
24 pub iterations: u32,
25
26 #[arg(long, short = 'd', default_value_t = DEFAULT_DURATION)]
27 pub duration: u32,
28
29 #[arg(long)]
30 pub only: Option<u32>,
31
32 #[arg(long, default_value = "benchmarks/items.html")]
33 pub output: PathBuf,
34
35 #[arg(long)]
36 pub no_html: bool,
37}
38
39impl TryFrom<&ItemsArgs> for RunParameters {
40 type Error = RunParametersError;
41
42 fn try_from(args: &ItemsArgs) -> Result<Self, Self::Error> {
43 let fight_duration = FightDurationSeconds::try_from(args.duration)?;
44 let iterations = IterationCount::try_from(args.iterations)?;
45
46 Ok(Self::new(iterations, fight_duration))
47 }
48}
49
50pub(crate) fn run(args: &ItemsArgs) -> Result<()> {
51 let parameters = RunParameters::try_from(args)?;
52 let spec_filter: Vec<SpecId> = args
53 .specs
54 .iter()
55 .map(|slug| {
56 SpecId::from_manifest_slug(slug).ok_or_else(|| anyhow!("Unknown spec slug: {slug}"))
57 })
58 .collect::<Result<Vec<_>>>()?;
59
60 let matrix = runner::run_matrix(&spec_filter, parameters, args.only)
61 .context("items matrix run failed")?;
62
63 report::print_console_summary(&matrix);
64
65 if !args.no_html {
66 report::generate(&args.output, &matrix)
67 .with_context(|| format!("failed to write HTML report to {}", args.output.display()))?;
68 let displayed_path =
69 directory::canonicalize(&args.output).unwrap_or_else(|_| args.output.clone());
70
71 output::success(&format!(
72 "Report written to file://{}",
73 displayed_path.display(),
74 ));
75 }
76
77 Ok(())
78}