Skip to main content

jellyflow_core/ops/
build.rs

1use crate::core::{BindingId, EdgeId, Graph, GroupId, NodeId, PortId, StickyNoteId};
2use crate::ops::{GraphMutationPlanner, GraphOp, GraphTransaction};
3
4/// Builder helpers for constructing safe, reversible edit operations.
5///
6/// These helpers:
7/// - snapshot the removed data needed for undo,
8/// - produce ops in a valid apply order,
9/// - use deterministic ordering for stability.
10pub trait GraphOpBuilderExt {
11    /// Builds a `RemoveEdge` op for an existing edge.
12    fn build_remove_edge_op(&self, id: EdgeId) -> Option<GraphOp>;
13
14    /// Builds a `RemovePort` op for an existing port, including incident edges.
15    fn build_remove_port_op(&self, id: PortId) -> Option<GraphOp>;
16
17    /// Builds ops that disconnect all edges incident to the port.
18    ///
19    /// The ops are returned in deterministic order.
20    fn build_disconnect_port_ops(&self, id: PortId) -> Option<Vec<GraphOp>>;
21
22    /// Builds a transaction that removes a port (and its incident edges).
23    fn build_remove_port_tx(
24        &self,
25        id: PortId,
26        label: impl Into<String>,
27    ) -> Option<GraphTransaction>;
28
29    /// Builds a `RemoveNode` op for an existing node, including owned ports and incident edges.
30    fn build_remove_node_op(&self, id: NodeId) -> Option<GraphOp>;
31
32    /// Builds a transaction that removes a node (and its ports/edges).
33    fn build_remove_node_tx(
34        &self,
35        id: NodeId,
36        label: impl Into<String>,
37    ) -> Option<GraphTransaction>;
38
39    /// Builds a `RemoveGroup` op for an existing group, including nodes detached from it.
40    fn build_remove_group_op(&self, id: GroupId) -> Option<GraphOp>;
41
42    /// Builds a transaction that removes a group (and detaches any child nodes).
43    fn build_remove_group_tx(
44        &self,
45        id: GroupId,
46        label: impl Into<String>,
47    ) -> Option<GraphTransaction>;
48
49    /// Builds a `RemoveStickyNote` op for an existing sticky note, including attached bindings.
50    fn build_remove_sticky_note_op(&self, id: StickyNoteId) -> Option<GraphOp>;
51
52    /// Builds a transaction that removes a sticky note and attached bindings.
53    fn build_remove_sticky_note_tx(
54        &self,
55        id: StickyNoteId,
56        label: impl Into<String>,
57    ) -> Option<GraphTransaction>;
58
59    /// Builds a `RemoveBinding` op for an existing binding.
60    fn build_remove_binding_op(&self, id: BindingId) -> Option<GraphOp>;
61
62    /// Builds a transaction that removes a binding.
63    fn build_remove_binding_tx(
64        &self,
65        id: BindingId,
66        label: impl Into<String>,
67    ) -> Option<GraphTransaction>;
68}
69
70impl GraphOpBuilderExt for Graph {
71    fn build_remove_edge_op(&self, id: EdgeId) -> Option<GraphOp> {
72        GraphMutationPlanner::new(self).remove_edge_op(id).ok()
73    }
74
75    fn build_remove_port_op(&self, id: PortId) -> Option<GraphOp> {
76        GraphMutationPlanner::new(self).remove_port_op(id).ok()
77    }
78
79    fn build_disconnect_port_ops(&self, id: PortId) -> Option<Vec<GraphOp>> {
80        GraphMutationPlanner::new(self).disconnect_port_ops(id).ok()
81    }
82
83    fn build_remove_port_tx(
84        &self,
85        id: PortId,
86        label: impl Into<String>,
87    ) -> Option<GraphTransaction> {
88        GraphMutationPlanner::new(self)
89            .remove_port_tx(id, label)
90            .ok()
91    }
92
93    fn build_remove_node_op(&self, id: NodeId) -> Option<GraphOp> {
94        GraphMutationPlanner::new(self).remove_node_op(id).ok()
95    }
96
97    fn build_remove_node_tx(
98        &self,
99        id: NodeId,
100        label: impl Into<String>,
101    ) -> Option<GraphTransaction> {
102        GraphMutationPlanner::new(self)
103            .remove_node_tx(id, label)
104            .ok()
105    }
106
107    fn build_remove_group_op(&self, id: GroupId) -> Option<GraphOp> {
108        GraphMutationPlanner::new(self).remove_group_op(id).ok()
109    }
110
111    fn build_remove_group_tx(
112        &self,
113        id: GroupId,
114        label: impl Into<String>,
115    ) -> Option<GraphTransaction> {
116        GraphMutationPlanner::new(self)
117            .remove_group_tx(id, label)
118            .ok()
119    }
120
121    fn build_remove_sticky_note_op(&self, id: StickyNoteId) -> Option<GraphOp> {
122        GraphMutationPlanner::new(self)
123            .remove_sticky_note_op(id)
124            .ok()
125    }
126
127    fn build_remove_sticky_note_tx(
128        &self,
129        id: StickyNoteId,
130        label: impl Into<String>,
131    ) -> Option<GraphTransaction> {
132        GraphMutationPlanner::new(self)
133            .remove_sticky_note_tx(id, label)
134            .ok()
135    }
136
137    fn build_remove_binding_op(&self, id: BindingId) -> Option<GraphOp> {
138        GraphMutationPlanner::new(self).remove_binding_op(id).ok()
139    }
140
141    fn build_remove_binding_tx(
142        &self,
143        id: BindingId,
144        label: impl Into<String>,
145    ) -> Option<GraphTransaction> {
146        GraphMutationPlanner::new(self)
147            .remove_binding_tx(id, label)
148            .ok()
149    }
150}