Skip to main content

jellyflow_core/ops/fragment/
remap.rs

1use uuid::Uuid;
2
3use crate::core::{BindingId, EdgeId, GroupId, NodeId, PortId, StickyNoteId, SymbolId};
4
5/// Seed used for deterministic ID remapping.
6///
7/// Using different seeds yields different IDs while keeping determinism for a given paste action.
8#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
9pub struct IdRemapSeed(pub Uuid);
10
11impl IdRemapSeed {
12    pub fn new_random() -> Self {
13        Self(Uuid::new_v4())
14    }
15}
16
17/// Deterministic ID remapper (UUID v5 under a caller-provided seed).
18#[derive(Debug, Clone)]
19pub struct IdRemapper {
20    seed: IdRemapSeed,
21}
22
23impl IdRemapper {
24    pub fn new(seed: IdRemapSeed) -> Self {
25        Self { seed }
26    }
27
28    fn remap_uuid(&self, old: Uuid) -> Uuid {
29        // Use UUID v5 in a deterministic namespace to avoid collisions across elements.
30        // The caller should pick a new seed for each paste/duplicate action.
31        Uuid::new_v5(&self.seed.0, old.as_bytes())
32    }
33
34    pub fn remap_node(&self, id: NodeId) -> NodeId {
35        NodeId(self.remap_uuid(id.0))
36    }
37
38    pub fn remap_port(&self, id: PortId) -> PortId {
39        PortId(self.remap_uuid(id.0))
40    }
41
42    pub fn remap_edge(&self, id: EdgeId) -> EdgeId {
43        EdgeId(self.remap_uuid(id.0))
44    }
45
46    pub fn remap_group(&self, id: GroupId) -> GroupId {
47        GroupId(self.remap_uuid(id.0))
48    }
49
50    pub fn remap_note(&self, id: StickyNoteId) -> StickyNoteId {
51        StickyNoteId(self.remap_uuid(id.0))
52    }
53
54    pub fn remap_symbol(&self, id: SymbolId) -> SymbolId {
55        SymbolId(self.remap_uuid(id.0))
56    }
57
58    pub fn remap_binding(&self, id: BindingId) -> BindingId {
59        BindingId(self.remap_uuid(id.0))
60    }
61}