Skip to main content

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                if node.component.id.as_str() == "component.exec" {
13                    op.clone()
14                } else {
15                    format!("{}.{}", node.component.id, op)
16                }
17            } else {
18                node.component.id.to_string()
19            };
20            match classify_node_type(&comp_str) {
21                NodeKind::Adapter {
22                    namespace,
23                    adapter,
24                    operation,
25                } => {
26                    if !catalog.contains(&namespace, &adapter, &operation) {
27                        errors.push(format!(
28                            "adapter_resolvable: node #{idx} ('{node_id}') component '{}' missing adapter '{}.{}' operation '{}'",
29                            comp_str, namespace, adapter, operation
30                        ));
31                    }
32                }
33                NodeKind::Builtin(_) => {}
34            }
35        }
36        errors
37    }
38}