use super::{DeviceModel, PinModel};
use std::collections::HashMap;
pub fn generate_pin_capability_table(model: &DeviceModel) -> String {
let mut table = String::new();
table.push_str("# Pin Capabilities for ");
table.push_str(&model.name);
table.push_str("\n\n");
table.push_str("| Pin | Digital Input | Digital Output | Analog Input | Special Functions |\n");
table.push_str("|-----|--------------|----------------|--------------|-------------------|\n");
let mut pins: Vec<(&u8, &PinModel)> = model.pins.iter().collect();
pins.sort_by_key(|&(pin, _)| pin);
for (pin, pin_model) in pins {
let digital_input = if pin_model.capabilities.contains(&"DigitalInput".to_string()) {
"✓"
} else {
" "
};
let digital_output = if pin_model.capabilities.contains(&"DigitalOutput".to_string()) {
"✓"
} else {
" "
};
let analog_input = if pin_model.capabilities.contains(&"AnalogInput".to_string()) {
"✓"
} else {
" "
};
let special_functions: Vec<String> = pin_model.capabilities.iter()
.filter(|&cap| {
!cap.contains("DigitalInput") &&
!cap.contains("DigitalOutput") &&
!cap.contains("AnalogInput")
})
.cloned()
.collect();
let special = if special_functions.is_empty() {
" ".to_string()
} else {
special_functions.join(", ")
};
table.push_str(&format!("| {} | {} | {} | {} | {} |\n", pin, digital_input, digital_output, analog_input, special));
}
let mut encoder_pairs = HashMap::new();
for (pin, pin_model) in &model.pins {
for capability in &pin_model.capabilities {
if capability.starts_with("Encoder_") && capability.len() >= 10 {
let encoder_id = &capability[8..capability.len() - 1]; let role = &capability[capability.len() - 1..];
encoder_pairs
.entry(encoder_id.to_string())
.or_insert_with(HashMap::new)
.insert(role.to_string(), *pin);
}
}
}
if !encoder_pairs.is_empty() {
table.push_str("\n## Encoder Pairs\n\n");
table.push_str("| Encoder | Pin A | Pin B |\n");
table.push_str("|---------|-------|-------|\n");
let mut encoder_ids: Vec<&String> = encoder_pairs.keys().collect();
encoder_ids.sort();
for encoder_id in encoder_ids {
let pins = encoder_pairs.get(encoder_id).unwrap();
let pin_a = pins.get("A").unwrap_or(&0);
let pin_b = pins.get("B").unwrap_or(&0);
table.push_str(&format!("| {} | {} | {} |\n", encoder_id, pin_a, pin_b));
}
}
let mut matrix_rows = Vec::new();
let mut matrix_cols = Vec::new();
for (pin, pin_model) in &model.pins {
for capability in &pin_model.capabilities {
if capability.starts_with("MatrixKeyboard_Row") {
matrix_rows.push((*pin, capability.clone()));
} else if capability.starts_with("MatrixKeyboard_Col") {
matrix_cols.push((*pin, capability.clone()));
}
}
}
if !matrix_rows.is_empty() && !matrix_cols.is_empty() {
table.push_str("\n## Matrix Keyboard\n\n");
matrix_rows.sort_by(|a, b| a.1.cmp(&b.1));
matrix_cols.sort_by(|a, b| a.1.cmp(&b.1));
table.push_str("### Rows\n\n");
table.push_str("| Pin | Row |\n");
table.push_str("|-----|-----|\n");
for (pin, capability) in &matrix_rows {
let row = &capability[17..]; table.push_str(&format!("| {} | {} |\n", pin, row));
}
table.push_str("\n### Columns\n\n");
table.push_str("| Pin | Column |\n");
table.push_str("|-----|--------|\n");
for (pin, capability) in &matrix_cols {
let col = &capability[17..]; table.push_str(&format!("| {} | {} |\n", pin, col));
}
}
table
}