reactive_graph_table_model/
container.rs1use std::fmt::Display;
2use std::fmt::Formatter;
3use std::marker::PhantomData;
4use std::vec::IntoIter;
5use table_to_html::HtmlTable;
6use tabled::Table;
7use tabled::Tabled;
8use tabled::settings::Style;
9
10pub trait TableContainer: Display {
11 fn table(&self) -> Table;
12
13 fn markdown_table(&self) -> Table;
14
15 fn html_table(&self) -> HtmlTable;
16}
17
18pub trait TableOptions: Sized {
19 fn options(table: &mut Table) -> &mut Table;
20}
21
22#[derive(Debug)]
23pub enum TableOutputFormat {
24 Table,
25 MarkdownTable,
26 HtmlTable,
27}
28
29#[derive(Clone, Debug)]
30pub enum TableInlineFormat {
31 Table,
32 Html,
33}
34
35pub trait TableInlineFormatSetter {
36 fn set_table_inline_format(&mut self, table_inline_format: TableInlineFormat);
37}
38
39impl Default for TableInlineFormat {
40 fn default() -> Self {
41 Self::Table
42 }
43}
44
45pub struct DefaultTableOptions {}
46
47impl TableOptions for DefaultTableOptions {
48 fn options(table: &mut Table) -> &mut Table {
49 table.with(Style::extended())
50 }
51}
52
53pub struct DefaultTableContainer<S, T: Clone + Tabled + From<S> + TableInlineFormatSetter, O: TableOptions>(
54 pub(crate) Vec<T>,
55 TableOutputFormat,
56 PhantomData<S>,
57 PhantomData<O>,
58);
59
60impl<S: 'static, T: Clone + Tabled + From<S> + TableInlineFormatSetter + 'static, O: TableOptions + 'static> DefaultTableContainer<S, T, O> {
61 pub fn into_boxed(self) -> Box<DefaultTableContainer<S, T, O>> {
62 Box::new(self)
63 }
64
65 pub fn into_html_table(mut self) -> Self {
66 self.0.iter_mut().for_each(|item| item.set_table_inline_format(TableInlineFormat::Html));
67 self.1 = TableOutputFormat::HtmlTable;
68 self
69 }
70
71 pub fn into_markdown_table(mut self) -> Self {
72 self.0.iter_mut().for_each(|item| item.set_table_inline_format(TableInlineFormat::Html));
73 self.1 = TableOutputFormat::MarkdownTable;
74 self
75 }
76}
77
78impl<S, T: Clone + Tabled + From<S> + TableInlineFormatSetter, O: TableOptions> TableContainer for DefaultTableContainer<S, T, O> {
79 fn table(&self) -> Table {
80 let mut table = Table::new(self.0.to_vec().iter());
81 O::options(&mut table).to_owned()
82 }
83
84 fn markdown_table(&self) -> Table {
85 Table::new(self.0.to_vec().iter()).with(Style::markdown()).to_owned()
86 }
87
88 fn html_table(&self) -> HtmlTable {
89 let items = self.0.to_vec();
90 HtmlTable::with_header(Vec::<Vec<String>>::from(Table::builder(&items)))
91 }
92}
93
94impl<S, T: Clone + Tabled + From<S> + TableInlineFormatSetter, O: TableOptions> From<Vec<S>> for DefaultTableContainer<S, T, O> {
95 fn from(entries: Vec<S>) -> Self {
96 DefaultTableContainer::<S, T, O>(entries.into_iter().map(From::from).collect(), TableOutputFormat::Table, PhantomData, PhantomData)
97 }
98}
99
100impl<S, T: Clone + Tabled + From<S> + TableInlineFormatSetter, O: TableOptions> From<S> for DefaultTableContainer<S, T, O> {
101 fn from(s: S) -> Self {
102 DefaultTableContainer::<S, T, O>(vec![s.into()], TableOutputFormat::Table, PhantomData, PhantomData)
103 }
104}
105
106impl<S, T: Clone + Tabled + From<S> + TableInlineFormatSetter, O: TableOptions> From<IntoIter<S>> for DefaultTableContainer<S, T, O> {
107 fn from(iter: IntoIter<S>) -> Self {
108 DefaultTableContainer::<S, T, O>(iter.map(From::from).collect(), TableOutputFormat::Table, PhantomData, PhantomData)
109 }
110}
111
112impl<S, T: Clone + Tabled + From<S> + TableInlineFormatSetter, O: TableOptions> FromIterator<S> for DefaultTableContainer<S, T, O> {
113 fn from_iter<TT: IntoIterator<Item = S>>(iter: TT) -> Self {
114 let entries = iter.into_iter().map(From::from).collect();
115 DefaultTableContainer::<S, T, O>(entries, TableOutputFormat::Table, PhantomData, PhantomData)
116 }
117}
118
119impl<S, T: Clone + Tabled + From<S> + TableInlineFormatSetter, O: TableOptions> Display for DefaultTableContainer<S, T, O> {
120 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
121 match self.1 {
122 TableOutputFormat::Table => {
123 write!(f, "{}", self.table())
124 }
125 TableOutputFormat::MarkdownTable => {
126 write!(f, "{}", self.markdown_table())
127 }
128 TableOutputFormat::HtmlTable => {
129 write!(f, "{}", self.html_table().to_string().trim())
130 }
131 }
132 }
133}