miden_debug_engine/profiling/
config.rs1use alloc::{boxed::Box, vec::Vec};
2#[cfg(feature = "std")]
3use std::path::PathBuf;
4
5#[cfg(feature = "std")]
6use miden_assembly_syntax::diagnostics::Report;
7
8use crate::profiling::instrument::Instrument;
9
10#[cfg(feature = "std")]
12#[derive(Default, Clone, Debug, clap::Args)]
13pub struct ProfilerCliArgs {
14 #[arg(long = "profiling-reports-dir", value_name = "DIRECTORY")]
17 pub reports_dir: Option<PathBuf>,
18 #[arg(
19 long = "profiling-instruments",
20 value_name = "VALUE",
21 value_delimiter = ','
22 )]
23 pub instruments: Vec<alloc::string::String>,
24}
25
26#[derive(Default)]
27pub struct ProfilerConfig {
28 pub instruments: Vec<Box<dyn Instrument>>,
30 #[cfg(feature = "std")]
32 pub reports_dir: Option<PathBuf>,
33}
34
35#[cfg(feature = "std")]
36impl TryFrom<ProfilerCliArgs> for ProfilerConfig {
37 type Error = Report;
38
39 fn try_from(mut args: ProfilerCliArgs) -> Result<Self, Self::Error> {
40 use crate::profiling::instrument_from_name;
41
42 let mut config = ProfilerConfig::default();
43
44 if let Some(ref path) = args.reports_dir
45 && path.exists()
46 && !path.is_dir()
47 {
48 return Err(Report::msg(format!(
49 "invalid profiling reports directory '{}': not a directory",
50 path.display()
51 )));
52 }
53
54 if args.reports_dir.is_some() && args.instruments.is_empty() {
55 return Err(Report::msg(
56 "profiling requires at least one instrument set with --profiling-instruments",
57 ));
58 }
59
60 if args.reports_dir.is_none() && !args.instruments.is_empty() {
61 return Err(Report::msg(
62 "profiling instruments require --profiling-reports-dir to be set",
63 ));
64 }
65
66 config.reports_dir = args.reports_dir;
67
68 args.instruments.sort();
69 args.instruments.dedup();
70 for name in &args.instruments {
71 let instrument = instrument_from_name(name, &config).map_err(Report::msg)?;
72 config.instruments.push(instrument);
73 }
74
75 Ok(config)
76 }
77}
78
79impl core::fmt::Debug for ProfilerConfig {
80 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
81 let instrument_names: Vec<&'static str> =
82 self.instruments.iter().map(|i| i.name()).collect();
83 let mut builder = f.debug_struct("ProfilerConfig");
84 builder.field("instruments", &instrument_names);
85 #[cfg(feature = "std")]
86 {
87 builder.field("reports_dir", &self.reports_dir);
88 }
89 builder.finish()
90 }
91}