use jellyflow_core::core::{
Binding, BindingId, CanvasPoint, Edge, EdgeId, EdgeKind, Graph, GraphBuilder, Group, GroupId,
Node, NodeId, NodeKindKey, Port, PortId, StickyNote, StickyNoteId,
};
use crate::io::NodeGraphViewState;
use crate::runtime::store::NodeGraphStore;
pub(super) fn default_editor_config() -> crate::io::NodeGraphEditorConfig {
crate::io::NodeGraphEditorConfig::default()
}
pub(super) fn make_store(graph: impl Into<Graph>) -> NodeGraphStore {
NodeGraphStore::new(
graph.into(),
NodeGraphViewState::default(),
default_editor_config(),
)
}
pub(super) fn fixture_insert_node(graph: &mut Graph, id: NodeId, node: Node) {
let mut builder = graph_builder_from_snapshot(graph);
builder.insert_node(id, node);
*graph = builder.build_unchecked();
}
pub(super) fn fixture_insert_port(graph: &mut Graph, id: PortId, port: Port) {
let mut builder = graph_builder_from_snapshot(graph);
builder.insert_port(id, port);
*graph = builder.build_unchecked();
}
pub(super) fn fixture_insert_group(graph: &mut Graph, id: GroupId, group: Group) {
let mut builder = graph_builder_from_snapshot(graph);
builder.insert_group(id, group);
*graph = builder.build_unchecked();
}
pub(super) fn fixture_insert_sticky_note(graph: &mut Graph, id: StickyNoteId, note: StickyNote) {
let mut builder = graph_builder_from_snapshot(graph);
builder.insert_sticky_note(id, note);
*graph = builder.build_unchecked();
}
pub(super) fn fixture_insert_binding(graph: &mut Graph, id: BindingId, binding: Binding) {
let mut builder = graph_builder_from_snapshot(graph);
builder.insert_binding(id, binding);
*graph = builder.build_unchecked();
}
pub(super) trait GraphFixtureUpdateExt {
fn update_node<R>(&mut self, id: &NodeId, f: impl FnOnce(&mut Node) -> R) -> Option<R>;
fn update_port<R>(&mut self, id: &PortId, f: impl FnOnce(&mut Port) -> R) -> Option<R>;
fn update_edge<R>(&mut self, id: &EdgeId, f: impl FnOnce(&mut Edge) -> R) -> Option<R>;
}
impl GraphFixtureUpdateExt for Graph {
fn update_node<R>(&mut self, id: &NodeId, f: impl FnOnce(&mut Node) -> R) -> Option<R> {
let mut builder = graph_builder_from_snapshot(self);
let updated = builder.update_node(id, f);
*self = builder.build_unchecked();
updated
}
fn update_port<R>(&mut self, id: &PortId, f: impl FnOnce(&mut Port) -> R) -> Option<R> {
let mut builder = graph_builder_from_snapshot(self);
let updated = builder.update_port(id, f);
*self = builder.build_unchecked();
updated
}
fn update_edge<R>(&mut self, id: &EdgeId, f: impl FnOnce(&mut Edge) -> R) -> Option<R> {
let mut builder = graph_builder_from_snapshot(self);
let updated = builder.update_edge(id, f);
*self = builder.build_unchecked();
updated
}
}
pub(super) fn fixture_remove_edge(graph: &mut Graph, id: &EdgeId) -> Option<Edge> {
let mut builder = graph_builder_from_snapshot(graph);
let removed = builder.remove_edge(id);
*graph = builder.build_unchecked();
removed
}
pub(super) fn fixture_clear_edges(graph: &mut Graph) {
let mut builder = graph_builder_from_snapshot(graph);
builder.clear_edges();
*graph = builder.build_unchecked();
}
fn graph_builder_from_snapshot(graph: &Graph) -> GraphBuilder {
let mut builder = GraphBuilder::new(graph.graph_id());
for (id, import) in graph.imports() {
builder.insert_import(*id, import.clone());
}
for (id, symbol) in graph.symbols() {
builder.insert_symbol(*id, symbol.clone());
}
for (id, node) in graph.nodes() {
builder.insert_node(*id, node.clone());
}
for (id, port) in graph.ports() {
builder.insert_port(*id, port.clone());
}
for (id, edge) in graph.edges() {
builder.insert_edge(*id, edge.clone());
}
for (id, group) in graph.groups() {
builder.insert_group(*id, group.clone());
}
for (id, note) in graph.sticky_notes() {
builder.insert_sticky_note(*id, note.clone());
}
for (id, binding) in graph.bindings() {
builder.insert_binding(*id, binding.clone());
}
builder
}
pub(super) fn make_graph() -> (
Graph,
NodeId,
NodeId,
jellyflow_core::core::PortId,
jellyflow_core::core::PortId,
EdgeId,
) {
let mut g = GraphBuilder::new(jellyflow_core::core::GraphId::from_u128(1));
let a = NodeId::new();
let b = NodeId::new();
let out_port = jellyflow_core::core::PortId::new();
let in_port = jellyflow_core::core::PortId::new();
let node_a = Node {
kind: NodeKindKey::new("demo.a"),
kind_version: 1,
pos: CanvasPoint { x: 0.0, y: 0.0 },
origin: None,
selectable: None,
focusable: None,
draggable: None,
connectable: None,
deletable: None,
parent: None,
extent: None,
expand_parent: None,
size: None,
hidden: false,
collapsed: false,
ports: vec![out_port],
data: serde_json::Value::Null,
};
let node_b = Node {
kind: NodeKindKey::new("demo.b"),
kind_version: 1,
pos: CanvasPoint { x: 100.0, y: 0.0 },
origin: None,
selectable: None,
focusable: None,
draggable: None,
connectable: None,
deletable: None,
parent: None,
extent: None,
expand_parent: None,
size: None,
hidden: false,
collapsed: false,
ports: vec![in_port],
data: serde_json::Value::Null,
};
g.insert_node(a, node_a);
g.insert_node(b, node_b);
g.insert_port(
out_port,
Port {
node: a,
key: jellyflow_core::core::PortKey::new("out"),
dir: jellyflow_core::core::PortDirection::Out,
kind: jellyflow_core::core::PortKind::Data,
capacity: jellyflow_core::core::PortCapacity::Multi,
connectable: None,
connectable_start: None,
connectable_end: None,
ty: None,
data: serde_json::Value::Null,
},
);
g.insert_port(
in_port,
Port {
node: b,
key: jellyflow_core::core::PortKey::new("in"),
dir: jellyflow_core::core::PortDirection::In,
kind: jellyflow_core::core::PortKind::Data,
capacity: jellyflow_core::core::PortCapacity::Single,
connectable: None,
connectable_start: None,
connectable_end: None,
ty: None,
data: serde_json::Value::Null,
},
);
let eid = EdgeId::new();
g.insert_edge(eid, Edge::new(EdgeKind::Data, out_port, in_port));
(g.into(), a, b, out_port, in_port, eid)
}