use super::context::CompilerContext;
use super::pass::CompilerPass;
use crate::Graph;
use crate::MergeStrategy;
use crate::node::NodeKind;
use crate::state::workflow_state::WorkflowState;
pub struct InlinePass;
impl InlinePass {
pub fn new() -> Self {
Self
}
}
impl Default for InlinePass {
fn default() -> Self {
Self::new()
}
}
impl<S: WorkflowState, M: MergeStrategy<S>> CompilerPass<S, M> for InlinePass {
fn name(&self) -> &str {
"inline"
}
fn run(&self, graph: &mut Graph<S, M>, ctx: &mut CompilerContext<S>) -> bool {
ctx.stats.total_nodes_before = graph.nodes.len();
let subgraph_nodes: Vec<String> = graph
.nodes
.iter()
.filter(|(_, kind)| matches!(kind, NodeKind::Subgraph(_)))
.map(|(name, _)| name.clone())
.collect();
ctx.stats.subgraph_count = subgraph_nodes.len();
if ctx.debug {
tracing::debug!(
subgraph_count = subgraph_nodes.len(),
"InlinePass: found subgraph nodes"
);
}
let mut modified = false;
for node_name in subgraph_nodes {
if let Some(NodeKind::Subgraph(_subgraph)) = graph.nodes.get(&node_name) {
ctx.stats.not_inlined_count += 1;
if ctx.debug {
tracing::debug!(
node = %node_name,
"InlinePass: skipping subgraph (inlining not yet implemented)"
);
}
}
let _ = &mut modified;
}
ctx.stats.total_nodes_after = graph.nodes.len();
modified
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{GraphBuilder, NodeKind, State, StateMerge, TaskNode};
#[test]
fn test_inline_pass_no_subgraphs() {
let mut builder = GraphBuilder::<State, StateMerge>::new("test");
builder.start("a");
builder.node("a", NodeKind::Task(TaskNode::new("a", |_| Ok(()))));
builder.end("a");
let mut graph = builder.build().unwrap();
let mut ctx = CompilerContext::new();
let pass = InlinePass::new();
let modified = pass.run(&mut graph, &mut ctx);
assert!(!modified);
assert_eq!(ctx.stats.subgraph_count, 0);
}
}