use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq)]
pub struct DeadCodeModule {
pub name: String,
pub size_bytes: u64,
pub is_optional: bool,
pub feature_flag: String,
}
#[derive(Debug)]
pub struct DeadCodeEliminationAnalyzer {
pub dead_code_modules: HashMap<String, DeadCodeModule>,
pub total_savings_bytes: u64,
}
impl DeadCodeEliminationAnalyzer {
pub fn new() -> Self {
let mut dead_code_modules = HashMap::new();
dead_code_modules.insert(
"developer_tools".to_string(),
DeadCodeModule {
name: "developer_tools".to_string(),
size_bytes: 45_000, is_optional: true,
feature_flag: "developer-tools".to_string(),
},
);
dead_code_modules.insert(
"advanced_examples".to_string(),
DeadCodeModule {
name: "advanced_examples".to_string(),
size_bytes: 35_000, is_optional: true,
feature_flag: "advanced-examples".to_string(),
},
);
dead_code_modules.insert(
"ecosystem_integration".to_string(),
DeadCodeModule {
name: "ecosystem_integration".to_string(),
size_bytes: 25_000, is_optional: true,
feature_flag: "ecosystem-integration".to_string(),
},
);
let total_savings_bytes: u64 = dead_code_modules
.values()
.map(|module| module.size_bytes)
.sum();
Self {
dead_code_modules,
total_savings_bytes,
}
}
pub fn is_dead_code(&self, module_name: &str) -> bool {
self.dead_code_modules.contains_key(module_name)
}
pub fn get_feature_flag(&self, module_name: &str) -> Option<&String> {
self.dead_code_modules
.get(module_name)
.map(|m| &m.feature_flag)
}
pub fn calculate_optimized_size(&self, base_size_bytes: u64, enabled_features: &[&str]) -> u64 {
let mut optimized_size = base_size_bytes;
for (module_name, module) in &self.dead_code_modules {
if !enabled_features.contains(&module.feature_flag.as_str()) {
optimized_size -= module.size_bytes;
}
}
optimized_size
}
pub fn get_savings_percentage(&self, base_size_bytes: u64) -> f64 {
(self.total_savings_bytes as f64 / base_size_bytes as f64) * 100.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dead_code_module_identification() {
let analyzer = DeadCodeEliminationAnalyzer::new();
assert!(analyzer.is_dead_code("developer_tools"));
assert!(analyzer.is_dead_code("advanced_examples"));
assert!(analyzer.is_dead_code("ecosystem_integration"));
assert!(!analyzer.is_dead_code("core_engine"));
}
#[test]
fn test_feature_flag_mapping() {
let analyzer = DeadCodeEliminationAnalyzer::new();
assert_eq!(
analyzer.get_feature_flag("developer_tools"),
Some(&"developer-tools".to_string())
);
assert_eq!(
analyzer.get_feature_flag("advanced_examples"),
Some(&"advanced-examples".to_string())
);
assert_eq!(
analyzer.get_feature_flag("ecosystem_integration"),
Some(&"ecosystem-integration".to_string())
);
assert_eq!(analyzer.get_feature_flag("core_engine"), None);
}
#[test]
fn test_bundle_size_calculation() {
let analyzer = DeadCodeEliminationAnalyzer::new();
let base_size = 378_000;
let full_size = analyzer.calculate_optimized_size(
base_size,
&[
"developer-tools",
"advanced-examples",
"ecosystem-integration",
],
);
assert_eq!(full_size, base_size);
let production_size = analyzer.calculate_optimized_size(base_size, &[]);
assert_eq!(production_size, base_size - analyzer.total_savings_bytes);
let partial_size = analyzer.calculate_optimized_size(base_size, &["developer-tools"]);
assert_eq!(partial_size, base_size - 35_000 - 25_000); }
#[test]
fn test_savings_percentage() {
let analyzer = DeadCodeEliminationAnalyzer::new();
let base_size = 378_000;
let savings_percentage = analyzer.get_savings_percentage(base_size);
let expected_percentage = (105_000.0 / 378_000.0) * 100.0;
assert!((savings_percentage - expected_percentage).abs() < 0.1);
}
#[test]
fn test_total_savings_amount() {
let analyzer = DeadCodeEliminationAnalyzer::new();
assert_eq!(analyzer.total_savings_bytes, 105_000);
}
#[test]
fn test_dead_code_modules_are_optional() {
let analyzer = DeadCodeEliminationAnalyzer::new();
for (_, module) in &analyzer.dead_code_modules {
assert!(
module.is_optional,
"Module {} should be marked as optional",
module.name
);
}
}
#[test]
fn test_production_build_size_target() {
let analyzer = DeadCodeEliminationAnalyzer::new();
let base_size = 378_000;
let production_size = analyzer.calculate_optimized_size(base_size, &[]);
assert_eq!(production_size, 273_000);
let reduction_percentage =
((base_size - production_size) as f64 / base_size as f64) * 100.0;
assert!((reduction_percentage - 27.8).abs() < 0.1);
}
#[test]
fn test_conditional_compilation_simulation() {
let analyzer = DeadCodeEliminationAnalyzer::new();
let configurations = vec![
("minimal", vec![]),
("standard", vec![]),
("production", vec![]),
(
"full",
vec![
"developer-tools",
"advanced-examples",
"ecosystem-integration",
],
),
];
for (config_name, features) in configurations {
let size = analyzer.calculate_optimized_size(378_000, &features);
match config_name {
"minimal" | "standard" | "production" => {
assert_eq!(size, 273_000);
}
"full" => {
assert_eq!(size, 378_000);
}
_ => {}
}
}
}
}