use crate::io::NodeGraphInteractionState;
use crate::rules::ConnectPlan;
use jellyflow_core::core::{EdgeId, Graph, PortId};
use jellyflow_core::interaction::NodeGraphConnectionMode;
use super::common::{
ConnectionEndpoints, ConnectionOpBuilder, add_existing_ports_edge_op, connection_exists,
edge_between, resolve_policy_checked_connection,
};
pub fn plan_connect_with_mode_and_policy(
graph: &Graph,
a: PortId,
b: PortId,
mode: NodeGraphConnectionMode,
state: &NodeGraphInteractionState,
) -> ConnectPlan {
match plan_resolved_connect(graph, a, b, mode, state) {
Ok(planned) => planned.into_plan(),
Err(plan) => plan,
}
}
pub(in crate::rules::connection) struct ResolvedConnectPlan<'a> {
endpoints: ConnectionEndpoints<'a>,
plan: ConnectPlan,
}
impl<'a> ResolvedConnectPlan<'a> {
pub(in crate::rules::connection) fn endpoints(&self) -> &ConnectionEndpoints<'a> {
&self.endpoints
}
pub(in crate::rules::connection) fn into_plan(self) -> ConnectPlan {
self.plan
}
}
pub(in crate::rules::connection) fn plan_resolved_connect<'a>(
graph: &'a Graph,
a: PortId,
b: PortId,
mode: NodeGraphConnectionMode,
state: &NodeGraphInteractionState,
) -> Result<ResolvedConnectPlan<'a>, ConnectPlan> {
let endpoints = match resolve_policy_checked_connection(graph, a, b, mode, state) {
Ok(endpoints) => endpoints,
Err(plan) => return Err(plan),
};
if connection_exists(
graph,
endpoints.edge_kind,
endpoints.from_id,
endpoints.to_id,
None,
) {
return Ok(ResolvedConnectPlan {
endpoints,
plan: ConnectPlan::accept(),
});
}
let mut ops = ConnectionOpBuilder::with_endpoint_capacity_disconnects(graph, &endpoints, None);
let add_edge = match add_existing_ports_edge_op(
graph,
EdgeId::new(),
edge_between(endpoints.edge_kind, endpoints.from_id, endpoints.to_id),
) {
Ok(op) => op,
Err(plan) => return Err(plan),
};
ops.push(add_edge);
Ok(ResolvedConnectPlan {
endpoints,
plan: ConnectPlan::from_ops(ops.into_ops()),
})
}
pub fn plan_connect_with_mode(
graph: &Graph,
a: PortId,
b: PortId,
mode: NodeGraphConnectionMode,
) -> ConnectPlan {
plan_connect_with_mode_and_policy(graph, a, b, mode, &NodeGraphInteractionState::default())
}
pub fn plan_connect(graph: &Graph, a: PortId, b: PortId) -> ConnectPlan {
plan_connect_with_mode(graph, a, b, NodeGraphConnectionMode::Strict)
}