1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
7pub enum AdvancedMetricsLevel {
8 None,
10 #[default]
12 Essential,
13 Comprehensive,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct BinaryExportConfig {
20 pub buffer_size: usize,
23 pub include_details: bool,
25 pub compression_level: u8,
27
28 pub advanced_metrics_level: AdvancedMetricsLevel,
31 pub source_analysis: bool,
33 pub lifecycle_timeline: bool,
35 pub container_analysis: bool,
37 pub fragmentation_analysis: bool,
39 pub thread_context_tracking: bool,
41 pub drop_chain_analysis: bool,
43 pub zst_analysis: bool,
45 pub health_scoring: bool,
47 pub performance_benchmarking: bool,
49 pub string_table_optimization: bool,
51}
52
53impl Default for BinaryExportConfig {
54 fn default() -> Self {
55 Self::performance_first()
56 }
57}
58
59impl BinaryExportConfig {
60 pub fn new() -> Self {
62 Self::default()
63 }
64
65 pub fn performance_first() -> Self {
67 Self {
68 buffer_size: 64 * 1024, include_details: true,
71 compression_level: 0, advanced_metrics_level: AdvancedMetricsLevel::Essential,
75 source_analysis: false, lifecycle_timeline: true, container_analysis: true, fragmentation_analysis: false, thread_context_tracking: true, drop_chain_analysis: false, zst_analysis: false, health_scoring: false, performance_benchmarking: false, string_table_optimization: true, }
86 }
87
88 pub fn debug_comprehensive() -> Self {
90 Self {
91 buffer_size: 128 * 1024, include_details: true,
94 compression_level: 1, advanced_metrics_level: AdvancedMetricsLevel::Comprehensive,
98 source_analysis: true,
99 lifecycle_timeline: true,
100 container_analysis: true,
101 fragmentation_analysis: true,
102 thread_context_tracking: true,
103 drop_chain_analysis: true,
104 zst_analysis: true,
105 health_scoring: true,
106 performance_benchmarking: true,
107 string_table_optimization: true,
108 }
109 }
110
111 pub fn minimal() -> Self {
113 Self {
114 buffer_size: 32 * 1024, include_details: false,
117 compression_level: 0,
118
119 advanced_metrics_level: AdvancedMetricsLevel::None,
121 source_analysis: false,
122 lifecycle_timeline: false,
123 container_analysis: false,
124 fragmentation_analysis: false,
125 thread_context_tracking: false,
126 drop_chain_analysis: false,
127 zst_analysis: false,
128 health_scoring: false,
129 performance_benchmarking: false,
130 string_table_optimization: false, }
132 }
133
134 pub fn validate_and_fix(&mut self) -> Vec<String> {
136 let mut warnings = Vec::new();
137
138 if self.buffer_size < 1024 {
140 warnings.push("Buffer size too small, setting to 1KB minimum".to_string());
141 self.buffer_size = 1024;
142 } else if self.buffer_size > 1024 * 1024 {
143 warnings.push("Buffer size too large, setting to 1MB maximum".to_string());
144 self.buffer_size = 1024 * 1024;
145 }
146
147 if self.compression_level > 9 {
149 warnings.push("Compression level too high, setting to maximum 9".to_string());
150 self.compression_level = 9;
151 }
152
153 match self.advanced_metrics_level {
155 AdvancedMetricsLevel::None => {
156 if self.source_analysis
158 || self.lifecycle_timeline
159 || self.container_analysis
160 || self.fragmentation_analysis
161 || self.thread_context_tracking
162 || self.drop_chain_analysis
163 || self.zst_analysis
164 || self.health_scoring
165 {
166 warnings.push("Advanced metrics level is None but some advanced features are enabled. Disabling advanced features.".to_string());
167 self.disable_all_advanced_features();
168 }
169 }
170 AdvancedMetricsLevel::Essential => {
171 if self.source_analysis {
173 warnings.push("Source analysis is expensive for Essential level. Consider using Comprehensive level or disabling source analysis.".to_string());
174 }
175 if self.fragmentation_analysis {
176 warnings.push("Fragmentation analysis is expensive for Essential level. Consider using Comprehensive level or disabling fragmentation analysis.".to_string());
177 }
178 }
179 AdvancedMetricsLevel::Comprehensive => {
180 }
182 }
183
184 if self.compression_level > 0
186 && self.advanced_metrics_level == AdvancedMetricsLevel::Comprehensive
187 {
188 warnings.push(
189 "High compression with comprehensive metrics may significantly impact performance"
190 .to_string(),
191 );
192 }
193
194 warnings
195 }
196
197 fn disable_all_advanced_features(&mut self) {
199 self.source_analysis = false;
200 self.lifecycle_timeline = false;
201 self.container_analysis = false;
202 self.fragmentation_analysis = false;
203 self.thread_context_tracking = false;
204 self.drop_chain_analysis = false;
205 self.zst_analysis = false;
206 self.health_scoring = false;
207 self.performance_benchmarking = false;
208 self.string_table_optimization = false;
209 }
210
211 pub fn has_advanced_metrics(&self) -> bool {
213 self.advanced_metrics_level != AdvancedMetricsLevel::None
214 || self.source_analysis
215 || self.lifecycle_timeline
216 || self.container_analysis
217 || self.fragmentation_analysis
218 || self.thread_context_tracking
219 || self.drop_chain_analysis
220 || self.zst_analysis
221 || self.health_scoring
222 || self.performance_benchmarking
223 || self.string_table_optimization
224 }
225
226 pub fn estimated_performance_impact(&self) -> f64 {
228 let mut impact = 0.0;
229
230 impact += match self.advanced_metrics_level {
232 AdvancedMetricsLevel::None => 0.0,
233 AdvancedMetricsLevel::Essential => 0.1,
234 AdvancedMetricsLevel::Comprehensive => 0.3,
235 };
236
237 if self.source_analysis {
239 impact += 0.2;
240 }
241 if self.fragmentation_analysis {
242 impact += 0.3;
243 }
244 if self.drop_chain_analysis {
245 impact += 0.15;
246 }
247 if self.zst_analysis {
248 impact += 0.1;
249 }
250 if self.health_scoring {
251 impact += 0.1;
252 }
253 if self.performance_benchmarking {
254 impact += 0.05;
255 }
256
257 impact += self.compression_level as f64 * 0.02;
259
260 impact.min(1.0) }
262}
263
264pub struct BinaryExportConfigBuilder {
266 config: BinaryExportConfig,
267}
268
269impl BinaryExportConfigBuilder {
270 pub fn new() -> Self {
272 Self {
273 config: BinaryExportConfig::performance_first(),
274 }
275 }
276
277 pub fn from_config(config: BinaryExportConfig) -> Self {
279 Self { config }
280 }
281
282 pub fn buffer_size(mut self, size: usize) -> Self {
284 self.config.buffer_size = size;
285 self
286 }
287
288 pub fn compression_level(mut self, level: u8) -> Self {
290 self.config.compression_level = level;
291 self
292 }
293
294 pub fn advanced_metrics_level(mut self, level: AdvancedMetricsLevel) -> Self {
296 self.config.advanced_metrics_level = level;
297 self
298 }
299
300 pub fn source_analysis(mut self, enable: bool) -> Self {
302 self.config.source_analysis = enable;
303 self
304 }
305
306 pub fn lifecycle_timeline(mut self, enable: bool) -> Self {
308 self.config.lifecycle_timeline = enable;
309 self
310 }
311
312 pub fn container_analysis(mut self, enable: bool) -> Self {
314 self.config.container_analysis = enable;
315 self
316 }
317
318 pub fn fragmentation_analysis(mut self, enable: bool) -> Self {
320 self.config.fragmentation_analysis = enable;
321 self
322 }
323
324 pub fn thread_context_tracking(mut self, enable: bool) -> Self {
326 self.config.thread_context_tracking = enable;
327 self
328 }
329
330 pub fn drop_chain_analysis(mut self, enable: bool) -> Self {
332 self.config.drop_chain_analysis = enable;
333 self
334 }
335
336 pub fn zst_analysis(mut self, enable: bool) -> Self {
338 self.config.zst_analysis = enable;
339 self
340 }
341
342 pub fn health_scoring(mut self, enable: bool) -> Self {
344 self.config.health_scoring = enable;
345 self
346 }
347
348 pub fn performance_benchmarking(mut self, enable: bool) -> Self {
350 self.config.performance_benchmarking = enable;
351 self
352 }
353
354 pub fn string_table_optimization(mut self, enable: bool) -> Self {
356 self.config.string_table_optimization = enable;
357 self
358 }
359
360 pub fn build(mut self) -> BinaryExportConfig {
362 let warnings = self.config.validate_and_fix();
363 if !warnings.is_empty() {
364 tracing::warn!("Configuration warnings: {:?}", warnings);
365 }
366 self.config
367 }
368}
369
370impl Default for BinaryExportConfigBuilder {
371 fn default() -> Self {
372 Self::new()
373 }
374}
375
376#[cfg(test)]
377mod tests {
378 use super::*;
379
380 #[test]
381 fn test_default_config() {
382 let config = BinaryExportConfig::default();
383 assert_eq!(
384 config.advanced_metrics_level,
385 AdvancedMetricsLevel::Essential
386 );
387 assert!(!config.source_analysis); assert!(config.lifecycle_timeline); assert!(config.container_analysis); }
391
392 #[test]
393 fn test_performance_first_config() {
394 let config = BinaryExportConfig::performance_first();
395 assert_eq!(config.compression_level, 0);
396 assert!(!config.source_analysis);
397 assert!(!config.fragmentation_analysis);
398 assert!(config.container_analysis); }
400
401 #[test]
402 fn test_debug_comprehensive_config() {
403 let config = BinaryExportConfig::debug_comprehensive();
404 assert_eq!(
405 config.advanced_metrics_level,
406 AdvancedMetricsLevel::Comprehensive
407 );
408 assert!(config.source_analysis);
409 assert!(config.fragmentation_analysis);
410 assert!(config.zst_analysis);
411 }
412
413 #[test]
414 fn test_minimal_config() {
415 let config = BinaryExportConfig::minimal();
416 assert_eq!(config.advanced_metrics_level, AdvancedMetricsLevel::None);
417 assert!(!config.source_analysis);
418 assert!(!config.lifecycle_timeline);
419 assert!(!config.container_analysis);
420 }
421
422 #[test]
423 fn test_config_validation() {
424 let mut config = BinaryExportConfig {
425 buffer_size: 100,
426 compression_level: 15,
427 ..Default::default()
428 };
429
430 let warnings = config.validate_and_fix();
431 assert!(!warnings.is_empty());
432 assert_eq!(config.buffer_size, 1024);
433 assert_eq!(config.compression_level, 9);
434 }
435
436 #[test]
437 fn test_config_builder() {
438 let config = BinaryExportConfigBuilder::new()
439 .advanced_metrics_level(AdvancedMetricsLevel::Comprehensive)
440 .source_analysis(true)
441 .fragmentation_analysis(true)
442 .compression_level(3)
443 .build();
444
445 assert_eq!(
446 config.advanced_metrics_level,
447 AdvancedMetricsLevel::Comprehensive
448 );
449 assert!(config.source_analysis);
450 assert!(config.fragmentation_analysis);
451 assert_eq!(config.compression_level, 3);
452 }
453
454 #[test]
455 fn test_performance_impact_estimation() {
456 let minimal = BinaryExportConfig::minimal();
457 let comprehensive = BinaryExportConfig::debug_comprehensive();
458
459 assert!(minimal.estimated_performance_impact() < 0.1);
460 assert!(comprehensive.estimated_performance_impact() > 0.5);
461 }
462
463 #[test]
464 fn test_has_advanced_metrics() {
465 let minimal = BinaryExportConfig::minimal();
466 let performance = BinaryExportConfig::performance_first();
467 let comprehensive = BinaryExportConfig::debug_comprehensive();
468
469 assert!(!minimal.has_advanced_metrics());
470 assert!(performance.has_advanced_metrics());
471 assert!(comprehensive.has_advanced_metrics());
472 }
473}
474
475#[derive(Debug, Clone, PartialEq, Default)]
477pub enum DashboardFormat {
478 Embedded,
480 #[default]
482 Lightweight,
483 Progressive,
485}
486
487#[derive(Debug, Clone, PartialEq, Default)]
489pub enum DataScope {
490 UserOnly,
492 SystemOnly,
494 #[default]
496 Both,
497}
498
499#[derive(Debug, Clone, PartialEq, Default)]
501pub enum PerformanceMode {
502 Fast,
504 #[default]
506 Complete,
507 Custom(Vec<AnalysisType>),
509}
510
511#[derive(Debug, Clone, PartialEq)]
513pub enum AnalysisType {
514 MemoryAnalysis,
515 LifecycleTracking,
516 VariableRelationships,
517 ComplexTypes,
518 UnsafeFFI,
519 PerformanceMetrics,
520}
521
522#[derive(Debug, Clone, Default)]
524pub struct DashboardOptions {
525 pub format: DashboardFormat,
527 pub scope: DataScope,
529 pub performance: PerformanceMode,
531 pub output_dir: Option<std::path::PathBuf>,
533 pub binary_config: BinaryExportConfig,
535}
536
537impl DashboardOptions {
538 pub fn new() -> Self {
540 Self::default()
541 }
542
543 pub fn format(mut self, format: DashboardFormat) -> Self {
545 self.format = format;
546 self
547 }
548
549 pub fn scope(mut self, scope: DataScope) -> Self {
551 self.scope = scope;
552 self
553 }
554
555 pub fn performance(mut self, performance: PerformanceMode) -> Self {
557 self.performance = performance;
558 self
559 }
560
561 pub fn output_dir<P: Into<std::path::PathBuf>>(mut self, dir: P) -> Self {
563 self.output_dir = Some(dir.into());
564 self
565 }
566
567 pub fn binary_config(mut self, config: BinaryExportConfig) -> Self {
569 self.binary_config = config;
570 self
571 }
572
573 pub fn parallel_processing(self, _enabled: bool) -> Self {
575 self
577 }
578
579 pub fn batch_size(self, _size: usize) -> Self {
581 self
583 }
584
585 pub fn buffer_size(mut self, size: usize) -> Self {
587 self.binary_config.buffer_size = size;
588 self
589 }
590
591 pub fn fast_preset() -> Self {
593 Self {
594 format: DashboardFormat::Lightweight,
595 scope: DataScope::UserOnly,
596 performance: PerformanceMode::Fast,
597 output_dir: None,
598 binary_config: BinaryExportConfig::performance_first(),
599 }
600 }
601
602 pub fn complete_preset() -> Self {
604 Self {
605 format: DashboardFormat::Progressive,
606 scope: DataScope::Both,
607 performance: PerformanceMode::Complete,
608 output_dir: None,
609 binary_config: BinaryExportConfig::debug_comprehensive(),
610 }
611 }
612
613 pub fn embedded_preset() -> Self {
615 Self {
616 format: DashboardFormat::Embedded,
617 scope: DataScope::Both,
618 performance: PerformanceMode::Complete,
619 output_dir: None,
620 binary_config: BinaryExportConfig::default(),
621 }
622 }
623}
624
625#[derive(Debug, Clone)]
627pub struct DashboardExportStats {
628 pub total_files_generated: usize,
630 pub html_size: usize,
632 pub total_json_size: usize,
634 pub processing_time_ms: u64,
636 pub allocations_processed: usize,
638 pub format_used: DashboardFormat,
640 pub scope_used: DataScope,
642}