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}