use crate::{BenchmarkReport, BenchmarkRunner, ComparisonPolicy};
use std::env;
#[derive(Clone, Debug)]
pub struct BenchmarkMainOptions {
pub suite: Option<String>,
pub filter_help: Option<String>,
pub comparison_policy: ComparisonPolicy,
pub save_results: bool,
}
impl Default for BenchmarkMainOptions {
fn default() -> Self {
Self {
suite: None,
filter_help: None,
comparison_policy: ComparisonPolicy::LatestCompatible,
save_results: true,
}
}
}
pub fn benchmark_filter_from_args(args: &[String]) -> Option<String> {
let separator_pos = args.iter().position(|arg| arg == "--");
if let Some(separator_pos) = separator_pos {
return args.get(separator_pos + 1).cloned();
}
args.iter()
.skip(1)
.find(|arg| !arg.starts_with("--") && !args[0].contains(arg.as_str()))
.cloned()
}
pub fn benchmark_filter_from_env() -> Option<String> {
let args: Vec<String> = env::args().collect();
benchmark_filter_from_args(&args)
}
pub fn run_benchmark_main(
options: BenchmarkMainOptions,
register: impl FnOnce(&BenchmarkRunner),
) -> BenchmarkReport {
let filter = benchmark_filter_from_env();
if let Some(filter) = filter.as_deref() {
eprintln!("Running benchmarks matching filter: '{filter}'");
if let Some(help) = options.filter_help.as_deref() {
eprintln!("Available filters: {help}");
}
eprintln!();
}
let mut runner = BenchmarkRunner::new().with_filter(filter.as_deref());
if let Some(suite) = options.suite {
runner = runner.with_suite(suite);
}
register(&runner);
if filter.is_some() {
eprintln!("\nBenchmark filtering complete.");
}
let report = runner.report();
report.print_summary_with(options.comparison_policy);
if options.save_results {
match report.save_to_default_location() {
Ok(path) => println!("\n💾 Results saved to: {}", path.display()),
Err(error) => println!("\n⚠️ Failed to save results: {error}"),
}
}
report
}