use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::Path;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MudaReport {
pub overproduction: f64,
pub waiting: f64,
pub inventory: f64,
pub transport: f64,
pub over_processing: f64,
pub motion: f64,
pub defects: f64,
pub total_score: f64,
pub grade: MudaGrade,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub file_details: HashMap<String, Vec<String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum MudaGrade {
Lean,
Efficient,
Moderate,
High,
Critical,
}
impl std::fmt::Display for MudaGrade {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
MudaGrade::Lean => write!(f, "Lean"),
MudaGrade::Efficient => write!(f, "Efficient"),
MudaGrade::Moderate => write!(f, "Moderate"),
MudaGrade::High => write!(f, "High"),
MudaGrade::Critical => write!(f, "Critical"),
}
}
}
impl MudaGrade {
fn from_score(score: f64) -> Self {
match score as u32 {
0..=20 => MudaGrade::Lean,
21..=40 => MudaGrade::Efficient,
41..=60 => MudaGrade::Moderate,
61..=80 => MudaGrade::High,
_ => MudaGrade::Critical,
}
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub fn calculate_muda_score(project_path: &Path) -> MudaReport {
let overproduction = measure_overproduction(project_path);
let waiting = measure_waiting(project_path);
let inventory = measure_inventory(project_path);
let transport = measure_transport(project_path);
let over_processing = measure_over_processing(project_path);
let motion = measure_motion(project_path);
let defects = measure_defects(project_path);
let mut file_details = HashMap::new();
let overproduction_files = collect_overproduction_files(project_path);
if !overproduction_files.is_empty() {
file_details.insert("Overproduction".to_string(), overproduction_files);
}
let inventory_files = collect_inventory_files(project_path);
if !inventory_files.is_empty() {
file_details.insert("Inventory".to_string(), inventory_files);
}
let over_processing_files = collect_over_processing_files(project_path);
if !over_processing_files.is_empty() {
file_details.insert("Over-processing".to_string(), over_processing_files);
}
let defect_files = collect_defect_files(project_path);
if !defect_files.is_empty() {
file_details.insert("Defects".to_string(), defect_files);
}
let total_score = (defects * 0.25)
+ (inventory * 0.20)
+ (over_processing * 0.15)
+ (overproduction * 0.15)
+ (waiting * 0.15)
+ (motion * 0.05)
+ (transport * 0.05);
let total_score = total_score.clamp(0.0, 100.0);
let grade = MudaGrade::from_score(total_score);
MudaReport {
overproduction,
waiting,
inventory,
transport,
over_processing,
motion,
defects,
total_score,
grade,
file_details,
}
}
include!("muda_handlers_measurement.rs");
include!("muda_handlers_metrics.rs");
include!("muda_handlers_tests.rs");