Skip to main content

yew_datatable_core/row/
data_table_row.rs

1//! A row in the table with associated metadata.
2//!
3//! `DataTableRow` wraps the original data type `T` and adds metadata needed
4//! for table operations like selection, expansion, and grouping.
5
6use crate::row::data_table_row_id::DataTableRowId;
7
8/// A row in the table with associated metadata.
9///
10/// Wraps the original data and adds metadata for table operations
11/// like selection, expansion, grouping, and nested row support.
12#[derive(Debug, Clone)]
13pub struct DataTableRow<T> {
14    /// Unique identifier for the row.
15    pub id: DataTableRowId,
16
17    /// The original row data.
18    pub original: T,
19
20    /// Index in the original data array.
21    pub original_index: usize,
22
23    /// Index in the current view (after filtering/sorting).
24    pub view_index: usize,
25
26    /// Depth level for nested/grouped rows.
27    pub depth: usize,
28
29    /// Parent row ID for nested rows.
30    pub parent_id: Option<DataTableRowId>,
31
32    /// Child row IDs for expandable rows.
33    pub sub_row_ids: Vec<DataTableRowId>,
34
35    /// Whether this is a group row (aggregated).
36    pub is_group_row: bool,
37
38    /// Group value for grouped rows.
39    pub group_value: Option<String>,
40
41    /// Whether this row can be expanded.
42    pub can_expand: bool,
43
44    /// Whether this row can be selected.
45    pub can_select: bool,
46}
47
48impl<T> DataTableRow<T> {
49    /// Creates a new row with the given ID and data.
50    ///
51    /// # Parameters
52    ///
53    /// - `id`: The unique row identifier.
54    /// - `original`: The original row data.
55    /// - `original_index`: The index in the original data array.
56    ///
57    /// # Returns
58    ///
59    /// - `DataTableRow<T>`: A new row with default metadata.
60    pub fn new(id: impl Into<DataTableRowId>, original: T, original_index: usize) -> Self {
61        Self {
62            id: id.into(),
63            original,
64            original_index,
65            view_index: original_index,
66            depth: 0,
67            parent_id: None,
68            sub_row_ids: Vec::new(),
69            is_group_row: false,
70            group_value: None,
71            can_expand: false,
72            can_select: true,
73        }
74    }
75
76    /// Creates a row from index (using index as ID).
77    ///
78    /// # Parameters
79    ///
80    /// - `original`: The original row data.
81    /// - `index`: The row index used as both ID and original index.
82    ///
83    /// # Returns
84    ///
85    /// - `DataTableRow<T>`: A new row with index-based ID.
86    pub fn from_index(original: T, index: usize) -> Self {
87        // Create the row using the index as the ID.
88        Self::new(DataTableRowId::from_index(index), original, index)
89    }
90
91    /// Sets the view index.
92    ///
93    /// # Parameters
94    ///
95    /// - `index`: The new view index.
96    ///
97    /// # Returns
98    ///
99    /// - `Self`: The modified row.
100    pub fn with_view_index(mut self, index: usize) -> Self {
101        // Update the view index.
102        self.view_index = index;
103        self
104    }
105
106    /// Sets the depth level.
107    ///
108    /// # Parameters
109    ///
110    /// - `depth`: The nesting depth level.
111    ///
112    /// # Returns
113    ///
114    /// - `Self`: The modified row.
115    pub fn with_depth(mut self, depth: usize) -> Self {
116        // Update the depth level.
117        self.depth = depth;
118        self
119    }
120
121    /// Sets the parent row ID.
122    ///
123    /// # Parameters
124    ///
125    /// - `parent_id`: The parent row identifier.
126    ///
127    /// # Returns
128    ///
129    /// - `Self`: The modified row.
130    pub fn with_parent(mut self, parent_id: DataTableRowId) -> Self {
131        // Set the parent row reference.
132        self.parent_id = Some(parent_id);
133        self
134    }
135
136    /// Sets the sub-row IDs.
137    ///
138    /// # Parameters
139    ///
140    /// - `sub_row_ids`: The child row identifiers.
141    ///
142    /// # Returns
143    ///
144    /// - `Self`: The modified row.
145    pub fn with_sub_rows(mut self, sub_row_ids: Vec<DataTableRowId>) -> Self {
146        // Set the child row IDs and update expandability.
147        self.sub_row_ids = sub_row_ids;
148        self.can_expand = !self.sub_row_ids.is_empty();
149        self
150    }
151
152    /// Marks this as a group row.
153    ///
154    /// # Parameters
155    ///
156    /// - `group_value`: The group value label.
157    ///
158    /// # Returns
159    ///
160    /// - `Self`: The modified row.
161    pub fn as_group_row(mut self, group_value: String) -> Self {
162        // Mark as group row and set the value.
163        self.is_group_row = true;
164        self.group_value = Some(group_value);
165        self
166    }
167
168    /// Sets whether this row can be selected.
169    ///
170    /// # Parameters
171    ///
172    /// - `can_select`: Whether the row is selectable.
173    ///
174    /// # Returns
175    ///
176    /// - `Self`: The modified row.
177    pub fn with_can_select(mut self, can_select: bool) -> Self {
178        // Update the selectable flag.
179        self.can_select = can_select;
180        self
181    }
182
183    /// Returns a reference to the original data.
184    ///
185    /// # Returns
186    ///
187    /// - `&T`: A reference to the original row data.
188    pub fn data(&self) -> &T {
189        &self.original
190    }
191
192    /// Returns a mutable reference to the original data.
193    ///
194    /// # Returns
195    ///
196    /// - `&mut T`: A mutable reference to the original row data.
197    pub fn data_mut(&mut self) -> &mut T {
198        &mut self.original
199    }
200
201    /// Returns whether this row has sub-rows.
202    ///
203    /// # Returns
204    ///
205    /// - `bool`: Whether the row has child rows.
206    pub fn has_sub_rows(&self) -> bool {
207        !self.sub_row_ids.is_empty()
208    }
209
210    /// Returns whether this row is a leaf (no sub-rows).
211    ///
212    /// # Returns
213    ///
214    /// - `bool`: Whether the row is a leaf node.
215    pub fn is_leaf(&self) -> bool {
216        self.sub_row_ids.is_empty() && !self.is_group_row
217    }
218
219    /// Returns whether this row is a root row (no parent).
220    ///
221    /// # Returns
222    ///
223    /// - `bool`: Whether the row has no parent.
224    pub fn is_root(&self) -> bool {
225        self.parent_id.is_none()
226    }
227
228    /// Maps the row data to a new type.
229    ///
230    /// # Parameters
231    ///
232    /// - `f`: A function to transform the row data.
233    ///
234    /// # Returns
235    ///
236    /// - `DataTableRow<U>`: A new row with the transformed data.
237    pub fn map<U, F>(self, f: F) -> DataTableRow<U>
238    where
239        F: FnOnce(T) -> U,
240    {
241        // Transform the data while preserving metadata.
242        DataTableRow {
243            id: self.id,
244            original: f(self.original),
245            original_index: self.original_index,
246            view_index: self.view_index,
247            depth: self.depth,
248            parent_id: self.parent_id,
249            sub_row_ids: self.sub_row_ids,
250            is_group_row: self.is_group_row,
251            group_value: self.group_value,
252            can_expand: self.can_expand,
253            can_select: self.can_select,
254        }
255    }
256}
257
258impl<T: Clone> DataTableRow<T> {
259    /// Clones the row with a new view index.
260    ///
261    /// # Parameters
262    ///
263    /// - `view_index`: The new view index.
264    ///
265    /// # Returns
266    ///
267    /// - `Self`: A cloned row with the updated view index.
268    pub fn clone_with_view_index(&self, view_index: usize) -> Self {
269        // Clone the row and update the view index.
270        let mut row = self.clone();
271        row.view_index = view_index;
272        row
273    }
274}