flow_rs_core/groups/
group.rs

1//! Group data structure and basic operations
2
3use crate::types::{GroupId, NodeId, Position, Rect, Size};
4use std::collections::HashSet;
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9/// Node group with metadata and member management
10#[derive(Debug, Clone)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12pub struct Group {
13    pub id: GroupId,
14    pub name: Option<String>,
15    pub members: HashSet<NodeId>,
16    pub position: Position,
17    pub size: Size,
18    pub collapsed: bool,
19    pub color: Option<String>,
20    pub parent_group: Option<GroupId>,
21    pub child_groups: HashSet<GroupId>,
22}
23
24impl Group {
25    /// Create a new group with the given members
26    pub fn new(id: GroupId, members: HashSet<NodeId>) -> Self {
27        Self {
28            id,
29            name: None,
30            members,
31            position: Position::zero(),
32            size: Size::default(),
33            collapsed: false,
34            color: None,
35            parent_group: None,
36            child_groups: HashSet::new(),
37        }
38    }
39
40    /// Check if the group contains a specific node
41    pub fn contains_node(&self, node_id: &NodeId) -> bool {
42        self.members.contains(node_id)
43    }
44
45    /// Get the number of members in this group
46    pub fn member_count(&self) -> usize {
47        self.members.len()
48    }
49
50    /// Add a node to this group
51    pub fn add_member(&mut self, node_id: NodeId) -> bool {
52        self.members.insert(node_id)
53    }
54
55    /// Remove a node from this group
56    pub fn remove_member(&mut self, node_id: &NodeId) -> bool {
57        self.members.remove(node_id)
58    }
59
60    /// Get bounding rectangle for the group
61    pub fn bounds(&self) -> Rect {
62        Rect::from_pos_size(self.position, self.size)
63    }
64}