1use std::io::{
3 Error,
4 Write,
5};
6use std::iter::FromIterator;
7use std::slice::{
8 Iter,
9 IterMut,
10};
11use std::ops::{
13 Index,
14 IndexMut,
15};
16
17use super::Terminal;
18
19use super::format::{
20 ColumnPosition,
21 TableFormat,
22};
23use super::utils::NEWLINE;
24use super::Cell;
25
26#[derive(Clone, Debug, Hash, PartialEq, Eq)]
28pub struct Row {
29 cells: Vec<Cell>,
30}
31
32impl Row {
33 pub fn new(cells: Vec<Cell>) -> Row {
35 Row { cells }
36 }
37
38 pub fn empty() -> Row {
40 Self::new({
41 Cell::default();
42 vec![] as Vec<Cell>
43 })
44 }
45
46 pub(crate) fn column_count(&self) -> usize {
51 self.cells.iter().map(|c| c.get_hspan()).sum()
52 }
53
54 pub fn len(&self) -> usize {
56 self.cells.len()
57 }
59
60 pub fn is_empty(&self) -> bool {
62 self.cells.is_empty()
63 }
64
65 fn get_height(&self) -> usize {
68 let mut height = 1; for cell in &self.cells {
70 let h = cell.get_height();
71 if h > height {
72 height = h;
73 }
74 }
75 height
76 }
77
78 pub(crate) fn get_column_width(&self, column: usize, format: &TableFormat) -> usize {
82 let mut i = 0;
83 for c in &self.cells {
84 if i + c.get_hspan() > column {
85 if c.get_hspan() == 1 {
86 return c.get_width();
87 }
88 let (lp, rp) = format.get_padding();
89 let sep = format
90 .get_column_separator(ColumnPosition::Intern)
91 .map(|_| 1)
92 .unwrap_or_default();
93 let rem = lp + rp + sep;
94 let mut w = c.get_width();
95 if w > rem {
96 w -= rem;
97 } else {
98 w = 0;
99 }
100 return (w as f64 / c.get_hspan() as f64).ceil() as usize;
101 }
102 i += c.get_hspan();
103 }
104 0
105 }
106
107 pub fn get_cell(&self, idx: usize) -> Option<&Cell> {
109 self.cells.get(idx)
110 }
111
112 pub fn get_mut_cell(&mut self, idx: usize) -> Option<&mut Cell> {
114 self.cells.get_mut(idx)
115 }
116
117 pub fn set_cell(&mut self, cell: Cell, idx: usize) -> Result<(), &str> {
119 if idx >= self.len() {
120 return Err("Cannot find cell");
121 }
122 self.cells[idx] = cell;
123 Ok(())
124 }
125
126 pub fn add_cell(&mut self, cell: Cell) {
128 self.cells.push(cell);
129 }
130
131 pub fn insert_cell(&mut self, index: usize, cell: Cell) {
134 if index < self.cells.len() {
135 self.cells.insert(index, cell);
136 } else {
137 self.add_cell(cell);
138 }
139 }
140
141 pub fn remove_cell(&mut self, index: usize) {
143 if index < self.cells.len() {
144 self.cells.remove(index);
145 }
146 }
147
148 pub fn iter(&self) -> Iter<Cell> {
150 self.cells.iter()
151 }
152
153 pub fn iter_mut(&mut self) -> IterMut<Cell> {
155 self.cells.iter_mut()
156 }
157
158 fn __print<T: Write + ?Sized, F>(
160 &self,
161 out: &mut T,
162 format: &TableFormat,
163 col_width: &[usize],
164 f: F,
165 ) -> Result<usize, Error>
166 where
167 F: Fn(&Cell, &mut T, usize, usize, bool) -> Result<(), Error>,
168 {
169 let height = self.get_height();
170 for i in 0..height {
171 out.write_all(&vec![b' '; format.get_indent()])?;
173 format.print_column_separator(out, ColumnPosition::Left)?;
174 let (lp, rp) = format.get_padding();
175 let mut j = 0;
176 let mut hspan = 0; while j + hspan < col_width.len() {
178 out.write_all(&vec![b' '; lp])?; let skip_r_fill =
182 (j == col_width.len() - 1) && format.get_column_separator(ColumnPosition::Right).is_none();
183 match self.get_cell(j) {
184 Some(c) => {
185 let mut w = col_width[j + hspan..j + hspan + c.get_hspan()].iter().sum();
187 let real_span = c.get_hspan() - 1;
188 w += real_span * (lp + rp)
189 + real_span
190 * format
191 .get_column_separator(ColumnPosition::Intern)
192 .map(|_| 1)
193 .unwrap_or_default();
194 f(c, out, i, w, skip_r_fill)?;
196 hspan += real_span; },
198 None => f(&Cell::default(), out, i, col_width[j + hspan], skip_r_fill)?,
199 };
200 out.write_all(&vec![b' '; rp])?; if j + hspan < col_width.len() - 1 {
202 format.print_column_separator(out, ColumnPosition::Intern)?;
203 }
204 j += 1;
205 }
206 format.print_column_separator(out, ColumnPosition::Right)?;
207 out.write_all(NEWLINE)?;
208 }
209 Ok(height)
210 }
211
212 pub(crate) fn print<T: Write + ?Sized>(
216 &self,
217 out: &mut T,
218 format: &TableFormat,
219 col_width: &[usize],
220 ) -> Result<usize, Error> {
221 self.__print(out, format, col_width, Cell::print)
222 }
223
224 pub(crate) fn print_term<T: Terminal + ?Sized>(
228 &self,
229 out: &mut T,
230 format: &TableFormat,
231 col_width: &[usize],
232 ) -> Result<usize, Error> {
233 self.__print(out, format, col_width, Cell::print_term)
234 }
235
236 pub fn print_html<T: Write + ?Sized>(&self, out: &mut T, col_num: usize) -> Result<(), Error> {
240 let mut printed_columns = 0;
241 for cell in self.iter() {
242 printed_columns += cell.print_html(out)?;
243 }
244 for _ in 0..col_num - printed_columns {
246 Cell::default().print_html(out)?;
247 }
248 Ok(())
249 }
250}
251
252impl Default for Row {
253 fn default() -> Row {
254 Row::empty()
255 }
256}
257
258impl Index<usize> for Row {
259 type Output = Cell;
260 fn index(&self, idx: usize) -> &Self::Output {
261 &self.cells[idx]
262 }
263}
264
265impl IndexMut<usize> for Row {
266 fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
267 &mut self.cells[idx]
268 }
269}
270
271impl<A: ToString> FromIterator<A> for Row {
272 fn from_iter<T>(iterator: T) -> Row
273 where
274 T: IntoIterator<Item = A>,
275 {
276 Self::new(iterator.into_iter().map(|ref e| Cell::from(e)).collect())
277 }
278}
279
280impl<T, A> From<T> for Row
281where
282 A: ToString,
283 T: IntoIterator<Item = A>,
284{
285 fn from(it: T) -> Row {
286 Self::from_iter(it)
287 }
288}
289
290impl<'a> IntoIterator for &'a Row {
291 type Item = &'a Cell;
292 type IntoIter = Iter<'a, Cell>;
293 fn into_iter(self) -> Self::IntoIter {
294 self.iter()
295 }
296}
297
298impl<'a> IntoIterator for &'a mut Row {
307 type Item = &'a mut Cell;
308 type IntoIter = IterMut<'a, Cell>;
309 fn into_iter(self) -> Self::IntoIter {
310 self.iter_mut()
311 }
312}
313
314impl<S: ToString> Extend<S> for Row {
315 fn extend<T: IntoIterator<Item = S>>(&mut self, iter: T) {
316 self
317 .cells
318 .extend(iter.into_iter().map(|s| Cell::new(&s.to_string())));
319 }
320}
321
322#[macro_export]
351macro_rules! row {
352 (($($out:tt)*);) => (vec![$($out)*]);
353 (($($out:tt)*); $value:expr) => (vec![$($out)* $crate::cell!($value)]);
354 (($($out:tt)*); $value:expr, $($n:tt)*) => ($crate::row!(($($out)* $crate::cell!($value),); $($n)*));
355 (($($out:tt)*); $style:ident -> $value:expr) => (vec![$($out)* $crate::cell!($style -> $value)]);
356 (($($out:tt)*); $style:ident -> $value:expr, $($n: tt)*) => ($crate::row!(($($out)* $crate::cell!($style -> $value),); $($n)*));
357
358 ($($content:expr), *) => ($crate::Row::new(vec![$($crate::cell!($content)), *])); ($style:ident => $($content:expr), *) => ($crate::Row::new(vec![$($crate::cell!($style -> $content)), *]));
360 ($style:ident => $($content:expr,) *) => ($crate::Row::new(vec![$($crate::cell!($style -> $content)), *]));
361 ($($content:tt)*) => ($crate::Row::new($crate::row!((); $($content)*)));
362}
363
364#[cfg(test)]
365mod tests {
366 use super::*;
367
368 #[test]
369 fn row_default_empty() {
370 let row1 = Row::default();
371 assert_eq!(row1.len(), 0);
372 assert!(row1.is_empty());
373 }
374
375 #[test]
376 fn get_add_set_cell() {
377 let mut row = Row::from(vec!["foo", "bar", "foobar"]);
378 assert_eq!(row.len(), 3);
379 assert!(row.get_mut_cell(12).is_none());
380 let c1 = row.get_mut_cell(0).unwrap().clone();
381 assert_eq!(c1.get_content(), "foo");
382
383 let c1 = Cell::from(&"baz");
384 assert!(row.set_cell(c1.clone(), 1000).is_err());
385 assert!(row.set_cell(c1.clone(), 0).is_ok());
386 assert_eq!(row.get_cell(0).unwrap().get_content(), "baz");
387
388 row.add_cell(c1.clone());
389 assert_eq!(row.len(), 4);
390 assert_eq!(row.get_cell(3).unwrap().get_content(), "baz");
391 }
392
393 #[test]
394 fn insert_cell() {
395 let mut row = Row::from(vec!["foo", "bar", "foobar"]);
396 assert_eq!(row.len(), 3);
397 let cell = Cell::new("baz");
398 row.insert_cell(1000, cell.clone());
399 assert_eq!(row.len(), 4);
400 assert_eq!(row.get_cell(3).unwrap().get_content(), "baz");
401 row.insert_cell(1, cell.clone());
402 assert_eq!(row.len(), 5);
403 assert_eq!(row.get_cell(1).unwrap().get_content(), "baz");
404 }
405
406 #[test]
407 fn remove_cell() {
408 let mut row = Row::from(vec!["foo", "bar", "foobar"]);
409 assert_eq!(row.len(), 3);
410 row.remove_cell(1000);
411 assert_eq!(row.len(), 3);
412 row.remove_cell(1);
413 assert_eq!(row.len(), 2);
414 assert_eq!(row.get_cell(0).unwrap().get_content(), "foo");
415 assert_eq!(row.get_cell(1).unwrap().get_content(), "foobar");
416 }
417
418 #[test]
419 fn extend_row() {
420 let mut row = Row::from(vec!["foo", "bar", "foobar"]);
421 row.extend(vec!["A", "B", "C"]);
422 assert_eq!(row.len(), 6);
423 assert_eq!(row.get_cell(3).unwrap().get_content(), "A");
424 assert_eq!(row.get_cell(4).unwrap().get_content(), "B");
425 assert_eq!(row.get_cell(5).unwrap().get_content(), "C");
426 }
427}