1use std::str::FromStr;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4pub enum Section {
5 FunctionsTiming,
6 FunctionsAlloc,
7 FunctionsCpu,
8 Channels,
9 Streams,
10 Futures,
11 RwLocks,
12 Mutexes,
13 Threads,
14 Debug,
15}
16
17impl Section {
18 pub fn all() -> Vec<Section> {
19 vec![
20 Section::FunctionsTiming,
21 Section::FunctionsAlloc,
22 Section::FunctionsCpu,
23 Section::Channels,
24 Section::Streams,
25 Section::Futures,
26 Section::RwLocks,
27 Section::Mutexes,
28 Section::Threads,
29 Section::Debug,
30 ]
31 }
32
33 pub fn short_name(&self) -> &'static str {
34 match self {
35 Section::FunctionsTiming => "timing",
36 Section::FunctionsAlloc => "alloc",
37 Section::FunctionsCpu => "cpu",
38 Section::Channels => "channels",
39 Section::Streams => "streams",
40 Section::Futures => "futures",
41 Section::RwLocks => "rw_locks",
42 Section::Mutexes => "mutexes",
43 Section::Threads => "threads",
44 Section::Debug => "debug",
45 }
46 }
47
48 pub fn from_name(s: &str) -> Option<Section> {
49 match s.trim() {
50 "functions-timing" => Some(Section::FunctionsTiming),
51 "functions-alloc" => Some(Section::FunctionsAlloc),
52 "functions-cpu" => Some(Section::FunctionsCpu),
53 "channels" => Some(Section::Channels),
54 "streams" => Some(Section::Streams),
55 "futures" => Some(Section::Futures),
56 "rw_locks" => Some(Section::RwLocks),
57 "mutexes" => Some(Section::Mutexes),
58 "threads" => Some(Section::Threads),
59 "debug" => Some(Section::Debug),
60 _ => None,
61 }
62 }
63
64 pub fn from_env() -> Option<Vec<Section>> {
65 std::env::var("HOTPATH_META_REPORT").ok().map(|val| {
66 let mut sections = Vec::new();
67 for part in val.split(',') {
68 match part.trim() {
69 "all" => return Section::all(),
70 other => {
71 if let Some(s) = Section::from_name(other) {
72 if !sections.contains(&s) {
73 sections.push(s);
74 }
75 } else {
76 eprintln!("[hotpath-meta] Unknown report section: '{}'", other);
77 }
78 }
79 }
80 }
81 sections
82 })
83 }
84}
85
86#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
105pub enum Format {
106 #[default]
107 Table,
108 Json,
109 JsonPretty,
110 None,
111}
112
113impl FromStr for Format {
114 type Err = String;
115
116 fn from_str(s: &str) -> Result<Self, Self::Err> {
117 match s.to_lowercase().as_str() {
118 "table" => Ok(Format::Table),
119 "json" => Ok(Format::Json),
120 "json-pretty" | "jsonpretty" => Ok(Format::JsonPretty),
121 "none" => Ok(Format::None),
122 _ => Err(format!(
123 "unknown format '{}', expected: table, json, json-pretty, none",
124 s
125 )),
126 }
127 }
128}
129
130impl Format {
131 pub fn from_env() -> Self {
134 match std::env::var("HOTPATH_META_OUTPUT_FORMAT") {
135 Ok(v) => v
136 .parse()
137 .unwrap_or_else(|e| panic!("HOTPATH_META_OUTPUT_FORMAT: {}", e)),
138 Err(_) => Format::default(),
139 }
140 }
141}
142
143pub trait IntoF64 {
144 fn into_f64(self) -> f64;
145}
146
147impl IntoF64 for f64 {
148 fn into_f64(self) -> f64 {
149 self
150 }
151}
152
153impl IntoF64 for f32 {
154 fn into_f64(self) -> f64 {
155 self as f64
156 }
157}
158
159impl IntoF64 for i8 {
160 fn into_f64(self) -> f64 {
161 self as f64
162 }
163}
164
165impl IntoF64 for i16 {
166 fn into_f64(self) -> f64 {
167 self as f64
168 }
169}
170
171impl IntoF64 for i32 {
172 fn into_f64(self) -> f64 {
173 self as f64
174 }
175}
176
177impl IntoF64 for i64 {
178 fn into_f64(self) -> f64 {
179 self as f64
180 }
181}
182
183impl IntoF64 for u8 {
184 fn into_f64(self) -> f64 {
185 self as f64
186 }
187}
188
189impl IntoF64 for u16 {
190 fn into_f64(self) -> f64 {
191 self as f64
192 }
193}
194
195impl IntoF64 for u32 {
196 fn into_f64(self) -> f64 {
197 self as f64
198 }
199}
200
201impl IntoF64 for u64 {
202 fn into_f64(self) -> f64 {
203 self as f64
204 }
205}
206
207impl IntoF64 for isize {
208 fn into_f64(self) -> f64 {
209 self as f64
210 }
211}
212
213impl IntoF64 for usize {
214 fn into_f64(self) -> f64 {
215 self as f64
216 }
217}
218
219#[doc(hidden)]
220pub fn env_flag(name: &str) -> bool {
221 std::env::var(name)
222 .map(|v| v.eq_ignore_ascii_case("true") || v == "1")
223 .unwrap_or(false)
224}
225
226#[cfg(feature = "hotpath-meta")]
227pub(crate) fn resolve_timeout_duration(
228 default_duration: std::time::Duration,
229 env_var: &str,
230) -> Option<std::time::Duration> {
231 let effective_duration = std::env::var(env_var)
232 .ok()
233 .and_then(|value| value.parse::<u64>().ok())
234 .map(std::time::Duration::from_millis)
235 .unwrap_or(default_duration);
236
237 if effective_duration.is_zero() {
238 None
239 } else {
240 Some(effective_duration)
241 }
242}