use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use crate::error::GraphError;
use crate::stream_emitter::StreamSink;
use crate::workflow_state::WorkflowState;
use tokio_util::sync::CancellationToken;
pub trait StateProjector<S: WorkflowState>: Send + Sync {
fn execute<'a>(
&'a self,
outer: &'a mut S,
stream: Option<Arc<dyn StreamSink>>,
cancel: CancellationToken,
) -> Pin<Box<dyn Future<Output = Result<(), GraphError>> + Send + 'a>>;
fn graph_name(&self) -> &str;
fn node_count(&self) -> usize;
}
#[derive(Clone)]
pub struct CompiledSubgraph<S: WorkflowState> {
pub projector: Arc<dyn StateProjector<S>>,
pub max_steps: usize,
}
impl<S: WorkflowState> CompiledSubgraph<S> {
pub fn new(projector: Arc<dyn StateProjector<S>>, max_steps: usize) -> Self {
Self {
projector,
max_steps,
}
}
pub async fn execute(
&self,
outer: &mut S,
stream: Option<Arc<dyn StreamSink>>,
cancel: CancellationToken,
) -> Result<(), GraphError> {
self.projector.execute(outer, stream, cancel).await
}
pub fn graph_name(&self) -> &str {
self.projector.graph_name()
}
pub fn node_count(&self) -> usize {
self.projector.node_count()
}
}
impl<S: WorkflowState> std::fmt::Debug for CompiledSubgraph<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CompiledSubgraph")
.field("graph_name", &self.projector.graph_name())
.field("node_count", &self.projector.node_count())
.field("max_steps", &self.max_steps)
.finish()
}
}