Skip to main content

ansiq_core/
table.rs

1use crate::{Style, Text};
2
3#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
4pub struct Cell {
5    content: Text,
6    style: Style,
7    column_span: u16,
8}
9
10impl Cell {
11    pub fn new<T>(content: T) -> Self
12    where
13        T: Into<Text>,
14    {
15        Self {
16            content: content.into(),
17            style: Style::default(),
18            column_span: 1,
19        }
20    }
21
22    pub fn content<T>(mut self, content: T) -> Self
23    where
24        T: Into<Text>,
25    {
26        self.content = content.into();
27        self
28    }
29
30    pub const fn column_span(mut self, column_span: u16) -> Self {
31        self.column_span = column_span;
32        self
33    }
34
35    pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
36        self.style = style.into();
37        self
38    }
39
40    pub fn text(&self) -> &Text {
41        &self.content
42    }
43
44    pub const fn style_value(&self) -> Style {
45        self.style
46    }
47
48    pub const fn column_span_value(&self) -> u16 {
49        self.column_span
50    }
51
52    pub fn width(&self) -> usize {
53        self.content.width()
54    }
55
56    pub fn height(&self) -> usize {
57        self.content.height()
58    }
59}
60
61impl<T> From<T> for Cell
62where
63    T: Into<Text>,
64{
65    fn from(value: T) -> Self {
66        Self::new(value)
67    }
68}
69
70#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
71pub struct Row {
72    cells: Vec<Cell>,
73    height: u16,
74    top_margin: u16,
75    bottom_margin: u16,
76    style: Style,
77}
78
79impl Row {
80    pub fn new<T>(cells: T) -> Self
81    where
82        T: IntoIterator,
83        T::Item: Into<Cell>,
84    {
85        let cells: Vec<Cell> = cells.into_iter().map(Into::into).collect();
86        let height = cells
87            .iter()
88            .map(|cell| cell.height() as u16)
89            .max()
90            .unwrap_or(1)
91            .max(1);
92        Self {
93            cells,
94            height,
95            top_margin: 0,
96            bottom_margin: 0,
97            style: Style::default(),
98        }
99    }
100
101    pub fn cells<T>(mut self, cells: T) -> Self
102    where
103        T: IntoIterator,
104        T::Item: Into<Cell>,
105    {
106        self.cells = cells.into_iter().map(Into::into).collect();
107        self.height = self
108            .cells
109            .iter()
110            .map(|cell| cell.height() as u16)
111            .max()
112            .unwrap_or(1)
113            .max(1);
114        self
115    }
116
117    pub const fn height(mut self, height: u16) -> Self {
118        self.height = height;
119        self
120    }
121
122    pub const fn top_margin(mut self, margin: u16) -> Self {
123        self.top_margin = margin;
124        self
125    }
126
127    pub const fn bottom_margin(mut self, margin: u16) -> Self {
128        self.bottom_margin = margin;
129        self
130    }
131
132    pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
133        self.style = style.into();
134        self
135    }
136
137    pub fn cells_ref(&self) -> &[Cell] {
138        &self.cells
139    }
140
141    pub const fn height_value(&self) -> u16 {
142        self.height
143    }
144
145    pub const fn top_margin_value(&self) -> u16 {
146        self.top_margin
147    }
148
149    pub const fn bottom_margin_value(&self) -> u16 {
150        self.bottom_margin
151    }
152
153    pub const fn style_value(&self) -> Style {
154        self.style
155    }
156
157    pub const fn height_with_margin(&self) -> u16 {
158        self.height
159            .saturating_add(self.top_margin)
160            .saturating_add(self.bottom_margin)
161    }
162
163    pub fn column_count(&self) -> usize {
164        self.cells
165            .iter()
166            .map(|cell| cell.column_span.max(1) as usize)
167            .sum()
168    }
169}
170
171impl<T> From<T> for Row
172where
173    T: IntoIterator,
174    T::Item: Into<Cell>,
175{
176    fn from(value: T) -> Self {
177        Self::new(value)
178    }
179}
180
181impl<Item> FromIterator<Item> for Row
182where
183    Item: Into<Cell>,
184{
185    fn from_iter<Iter: IntoIterator<Item = Item>>(iter: Iter) -> Self {
186        Self::new(iter)
187    }
188}