use crate::error;
use crate::model::block::{Alignment, BlockContent, Caption, HasAlignment, HasCaption, Label};
use crate::model::inline::HasInlineContent;
use crate::model::inline::{Character, InlineContent};
use crate::model::{block::HasLabel, HasInnerContent};
#[cfg(feature = "fmt_json")]
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug)]
#[cfg_attr(feature = "fmt_json", derive(Serialize, Deserialize))]
pub struct Table {
#[cfg_attr(feature = "fmt_json", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(feature = "fmt_json", serde(default))]
label: Option<Label>,
columns: Vec<Column>,
rows: Vec<Row>,
#[cfg_attr(feature = "fmt_json", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(feature = "fmt_json", serde(default))]
caption: Option<Caption>,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "fmt_json", derive(Serialize, Deserialize))]
pub struct Column {
text: String,
alignment: Alignment,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "fmt_json", derive(Serialize, Deserialize))]
pub struct Row {
cells: Vec<Cell>,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "fmt_json", derive(Serialize, Deserialize))]
pub struct Cell {
#[cfg_attr(feature = "fmt_json", serde(skip_serializing_if = "Option::is_none"))]
#[cfg_attr(feature = "fmt_json", serde(default))]
label: Option<Label>,
inner: Vec<InlineContent>,
}
impl Default for Table {
fn default() -> Self {
Self {
label: None,
columns: Default::default(),
rows: Default::default(),
caption: None,
}
}
}
label_impl!(Table);
block_impls!(Table);
has_captioned_impls!(Table);
impl Table {
pub fn new(columns: &[Column]) -> Self {
Self {
label: None,
columns: columns.to_vec(),
rows: Default::default(),
caption: None,
}
}
pub fn has_columns(&self) -> bool {
!self.columns.is_empty()
}
pub fn columns(&self) -> &Vec<Column> {
&self.columns
}
pub fn add_column(&mut self, column: Column) {
self.columns.push(column)
}
pub fn add_columns(&mut self, columns: &[Column]) {
self.columns.extend_from_slice(columns)
}
pub fn has_rows(&self) -> bool {
!self.rows.is_empty()
}
pub fn rows(&self) -> &Vec<Row> {
&self.rows
}
pub fn add_row(&mut self, row: Row) {
self.rows.push(row)
}
pub fn add_rows(&mut self, rows: &[Row]) {
self.rows.extend_from_slice(rows)
}
}
impl From<String> for Column {
fn from(text: String) -> Self {
Self::new(&text)
}
}
impl From<&str> for Column {
fn from(text: &str) -> Self {
Self {
text: text.to_string(),
alignment: Default::default(),
}
}
}
impl From<(&str, Alignment)> for Column {
fn from(column: (&str, Alignment)) -> Self {
Self::from(&column)
}
}
impl From<&(&str, Alignment)> for Column {
fn from(column: &(&str, Alignment)) -> Self {
Self::with_alignment(column.0, column.1.clone())
}
}
alignment_impl!(Column);
impl Column {
pub fn new(text: &str) -> Self {
Self {
text: text.to_string(),
alignment: Default::default(),
}
}
pub fn with_alignment(text: &str, alignment: Alignment) -> Self {
Self {
text: text.to_string(),
alignment,
}
}
pub fn text(&self) -> &String {
&self.text
}
}
impl From<Vec<Cell>> for Row {
fn from(cells: Vec<Cell>) -> Self {
Self { cells }
}
}
impl Row {
pub fn new(cells: &[Cell]) -> Self {
Self {
cells: cells.to_vec(),
}
}
pub fn cells(&self) -> &Vec<Cell> {
&self.cells
}
pub fn add_cell(&mut self, cell: Cell) -> &mut Self {
self.cells.push(cell);
self
}
pub fn add_cells(&mut self, cells: &[Cell]) -> &mut Self {
self.cells.extend_from_slice(cells);
self
}
}
impl Default for Cell {
fn default() -> Self {
Cell::skip()
}
}
label_impl!(Cell);
has_inline_impls!(Cell);
impl Cell {
pub fn skip() -> Self {
Self {
label: None,
inner: Default::default(),
}
}
pub fn empty() -> Self {
Self {
label: None,
inner: vec![Character::NonBreakSpace.into()],
}
}
}