use std::collections::{BTreeMap, HashMap, HashSet};
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use std::time::Duration;
use crate::Result;
use crate::graph::command::NodeResult;
use crate::graph::reducer::StateReducer;
use crate::harness::ids::{GraphId, NodeId, RunId, ThreadId};
pub const START: &str = "__start__";
pub const END: &str = "__end__";
pub type NodeFuture<Update> = Pin<Box<dyn Future<Output = Result<NodeResult<Update>>> + Send>>;
pub type NodeHandler<State, Update> =
dyn Fn(State, NodeContext) -> NodeFuture<Update> + Send + Sync;
pub type RouterFn<State> = dyn Fn(&State) -> String + Send + Sync;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ForkId {
pub branch_index: usize,
pub node: NodeId,
}
impl ForkId {
pub fn new(branch_index: usize, node: NodeId) -> Self {
Self { branch_index, node }
}
}
#[derive(Clone, Debug)]
pub struct NodeContext {
pub node_id: NodeId,
pub run_id: RunId,
pub thread_id: Option<ThreadId>,
pub step: usize,
pub resume: Option<serde_json::Value>,
pub fork: Option<ForkId>,
pub send_arg: Option<serde_json::Value>,
pub root_run_id: Option<RunId>,
pub recursion_frames: Vec<crate::graph::recursion::RecursionFrame>,
pub child_runs: Option<crate::graph::recursion::ChildRunSink>,
}
#[derive(Clone, Debug, Default)]
pub(crate) struct NodeMeta {
pub(crate) kind: Option<String>,
pub(crate) interrupt: bool,
pub(crate) deferred: bool,
pub(crate) subgraph: bool,
pub(crate) command_destinations: Vec<NodeId>,
pub(crate) metadata: BTreeMap<String, String>,
}
pub(crate) struct BuilderNode<State, Update> {
#[allow(dead_code)]
pub(crate) id: NodeId,
pub(crate) handler: Arc<NodeHandler<State, Update>>,
}
impl<State, Update> Clone for BuilderNode<State, Update> {
fn clone(&self) -> Self {
Self {
id: self.id.clone(),
handler: self.handler.clone(),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Route(pub String);
impl Route {
pub fn new(label: impl ToString) -> Self {
Self(label.to_string())
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl std::fmt::Display for Route {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.0)
}
}
#[derive(Clone, Debug, Default)]
pub struct GraphDefaults {
pub recursion_limit: Option<usize>,
pub parallel: Option<bool>,
pub max_concurrency: Option<usize>,
pub node_timeout: Option<Duration>,
}
pub(crate) struct Branch<State> {
pub(crate) router: Arc<RouterFn<State>>,
pub(crate) routes: HashMap<String, NodeId>,
}
impl<State> Clone for Branch<State> {
fn clone(&self) -> Self {
Self {
router: self.router.clone(),
routes: self.routes.clone(),
}
}
}
pub struct GraphBuilder<State, Update> {
pub(crate) graph_id: GraphId,
pub(crate) name: Option<String>,
pub(crate) nodes: HashMap<NodeId, BuilderNode<State, Update>>,
pub(crate) edges: HashMap<NodeId, NodeId>,
pub(crate) branches: HashMap<NodeId, Branch<State>>,
pub(crate) command_nodes: HashSet<NodeId>,
pub(crate) waiting: HashMap<NodeId, HashSet<NodeId>>,
pub(crate) reducer: Option<Arc<dyn StateReducer<State, Update>>>,
pub(crate) recursion_limit: usize,
pub(crate) parallel: bool,
pub(crate) max_concurrency: Option<usize>,
pub(crate) node_timeout: Option<Duration>,
pub(crate) node_meta: HashMap<NodeId, NodeMeta>,
}