use crate::element::Element;
use crate::style::{Align, Border, Color, Common};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(rename_all = "snake_case"))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Copy, Debug)]
pub enum ColumnWidth {
Fixed(f32),
Flex(f32),
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(deny_unknown_fields))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Copy, Debug)]
pub struct TableColumn {
pub width: ColumnWidth,
#[cfg_attr(feature = "serde", serde(default))]
pub align: Align,
}
impl TableColumn {
pub fn fixed(width: f32) -> Self {
TableColumn {
width: ColumnWidth::Fixed(width),
align: Align::Start,
}
}
pub fn flex(weight: f32) -> Self {
TableColumn {
width: ColumnWidth::Flex(weight),
align: Align::Start,
}
}
pub fn align(mut self, align: Align) -> Self {
self.align = align;
self
}
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(deny_unknown_fields))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug)]
pub struct TableCell {
pub element: Element,
#[cfg_attr(feature = "serde", serde(default = "TableCell::default_span"))]
pub colspan: usize,
#[cfg_attr(feature = "serde", serde(default = "TableCell::default_span"))]
pub rowspan: usize,
#[cfg_attr(feature = "serde", serde(default))]
pub align: Option<Align>,
#[cfg_attr(feature = "serde", serde(default))]
pub background: Option<Color>,
#[cfg_attr(feature = "serde", serde(default))]
pub border: Option<Border>,
#[cfg_attr(feature = "serde", serde(default))]
pub padding: Option<f32>,
}
impl TableCell {
pub fn new(element: impl Into<Element>) -> Self {
TableCell {
element: element.into(),
colspan: 1,
rowspan: 1,
align: None,
background: None,
border: None,
padding: None,
}
}
#[cfg(feature = "serde")]
fn default_span() -> usize {
1
}
pub fn colspan(mut self, colspan: usize) -> Self {
self.colspan = colspan.max(1);
self
}
pub fn rowspan(mut self, rowspan: usize) -> Self {
self.rowspan = rowspan.max(1);
self
}
pub fn align(mut self, align: Align) -> Self {
self.align = Some(align);
self
}
pub fn background(mut self, color: Color) -> Self {
self.background = Some(color);
self
}
pub fn border(mut self, border: Border) -> Self {
self.border = Some(border);
self
}
pub fn padding(mut self, padding: f32) -> Self {
self.padding = Some(padding);
self
}
}
impl<T: Into<Element>> From<T> for TableCell {
fn from(value: T) -> Self {
TableCell::new(value)
}
}
pub trait TableRow {
fn cells(&self) -> Vec<TableCell>;
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(deny_unknown_fields))]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, Default)]
pub struct Table {
#[cfg_attr(feature = "serde", serde(default))]
pub columns: Vec<TableColumn>,
#[cfg_attr(feature = "serde", serde(default))]
pub header: Option<Vec<TableCell>>,
#[cfg_attr(feature = "serde", serde(default))]
pub rows: Vec<Vec<TableCell>>,
#[cfg_attr(feature = "serde", serde(default))]
pub striped: Option<Color>,
#[cfg_attr(feature = "serde", serde(default = "Table::default_cell_padding"))]
pub cell_padding: f32,
#[cfg_attr(feature = "serde", serde(skip))]
pub row_offset: usize,
#[cfg_attr(feature = "serde", serde(default))]
pub common: Common,
}
impl Table {
#[cfg(feature = "serde")]
fn default_cell_padding() -> f32 {
Table::new().cell_padding
}
pub fn new() -> Self {
Table {
cell_padding: 4.0,
..Default::default()
}
}
pub fn columns(mut self, columns: impl IntoIterator<Item = TableColumn>) -> Self {
self.columns = columns.into_iter().collect();
self
}
pub fn header(mut self, cells: impl IntoIterator<Item = impl Into<TableCell>>) -> Self {
self.header = Some(cells.into_iter().map(Into::into).collect());
self
}
pub fn rows(mut self, rows: impl IntoIterator<Item = impl IntoIterator<Item = impl Into<TableCell>>>) -> Self {
self.rows = rows.into_iter().map(|row| row.into_iter().map(Into::into).collect()).collect();
self
}
pub fn from_rows<T: TableRow>(mut self, items: &[T]) -> Self {
self.rows = items.iter().map(TableRow::cells).collect();
self
}
pub fn striped(mut self, color: Color) -> Self {
self.striped = Some(color);
self
}
pub fn cell_padding(mut self, padding: f32) -> Self {
self.cell_padding = padding;
self
}
pub fn width(mut self, width: f32) -> Self {
self.common.width = Some(width);
self
}
pub fn height(mut self, height: f32) -> Self {
self.common.height = Some(height);
self
}
pub fn flex(mut self, factor: f32) -> Self {
self.common.flex = Some(factor);
self
}
pub fn keep_with_next(mut self) -> Self {
self.common.keep_with_next = true;
self
}
}