greentic_flow/lint/
adapter_resolvable.rs

1use crate::{ir::NodeKind, ir::classify_node_type, registry::AdapterCatalog};
2use greentic_types::Flow;
3
4#[derive(Clone, Debug, Default)]
5pub struct AdapterResolvableRule;
6
7impl AdapterResolvableRule {
8    pub fn check(flow: &Flow, catalog: &AdapterCatalog) -> Vec<String> {
9        let mut errors = Vec::new();
10        for (idx, (node_id, node)) in flow.nodes.iter().enumerate() {
11            let comp_str = if let Some(op) = &node.component.operation {
12                format!("{}.{}", node.component.id, op)
13            } else {
14                node.component.id.to_string()
15            };
16            match classify_node_type(&comp_str) {
17                NodeKind::Adapter {
18                    namespace,
19                    adapter,
20                    operation,
21                } => {
22                    if !catalog.contains(&namespace, &adapter, &operation) {
23                        errors.push(format!(
24                            "adapter_resolvable: node #{idx} ('{node_id}') component '{}' missing adapter '{}.{}' operation '{}'",
25                            comp_str, namespace, adapter, operation
26                        ));
27                    }
28                }
29                NodeKind::Builtin(_) => {}
30            }
31        }
32        errors
33    }
34}