1use std::collections::HashMap;
6use vil_ir::core::WorkflowIR;
7use vil_types::QueueKind;
8
9use crate::traits::{Diagnostic, ValidationPass, ValidationReport};
10
11pub struct QueueCapabilityPass;
12
13impl ValidationPass for QueueCapabilityPass {
14 fn name(&self) -> &'static str {
15 "QueueCapabilityPass"
16 }
17
18 fn run(&self, ir: &WorkflowIR) -> ValidationReport {
19 let mut report = ValidationReport::new();
20
21 let mut port_connections: HashMap<(String, String), usize> = HashMap::new();
23
24 for route in &ir.routes {
25 let from_key = (route.from_process.clone(), route.from_port.clone());
26 let to_key = (route.to_process.clone(), route.to_port.clone());
27
28 *port_connections.entry(from_key).or_insert(0) += 1;
29 *port_connections.entry(to_key).or_insert(0) += 1;
30 }
31
32 for ((proc_name, port_name), count) in port_connections {
34 if count > 1 {
35 if let Some(proc_ir) = ir.processes.get(&proc_name) {
37 if let Some(iface) = ir.interfaces.get(&proc_ir.interface_name) {
38 if let Some(port) = iface.ports.get(&port_name) {
39 if port.queue_spec.kind == QueueKind::Spsc {
40 report.push(Diagnostic::error(
41 "E-QUEUE-01",
42 format!("Port '{}' on process '{}' has {} connections but is configured as Spsc. Change to Mpmc.", port_name, proc_name, count),
43 format!("{}.{}", proc_name, port_name),
44 ));
45 }
46 }
47 }
48 }
49 }
50 }
51
52 report
53 }
54}