1#[cfg(feature = "export")]
2use crate::Exporter;
3use crate::{Row, TableColumn, TableContext};
4use dioxus::prelude::*;
5
6#[allow(clippy::type_complexity, reason = "to provide internal API")]
41pub trait Columns<R: Row>: Clone + PartialEq + 'static {
42 fn column_names(&self) -> Vec<String>;
44 fn headers(&self) -> Vec<Box<dyn Fn(&TableContext<Self>, Vec<Attribute>) -> Element + '_>>;
46 fn columns(&self) -> Vec<Box<dyn Fn(&TableContext<Self>, &R, Vec<Attribute>) -> Element + '_>>;
48 fn filter(&self, row: &R) -> bool;
50 fn compare(&self) -> Vec<Box<dyn Fn(&R, &R) -> std::cmp::Ordering + '_>>;
52}
53
54#[cfg(feature = "export")]
58pub trait SerializableColumns<R: Row>: Columns<R> {
59 fn serialize_headers(&self) -> Vec<Box<dyn Fn() -> String + '_>>;
61 #[allow(clippy::type_complexity, reason = "to provide internal API")]
63 fn serialize_cell<E: Exporter>(
64 &self,
65 ) -> Vec<Box<dyn Fn(usize, usize, &R, &mut E) -> Result<(), E::Error> + '_>>;
66}
67
68macro_rules! columns {
69 ($($number:tt => $column:ident),*) => {
70 impl<$($column: TableColumn<R>),*, R: Row> Columns<R> for ($($column),*,) {
71 fn column_names(&self) -> Vec<String> {
72 vec![$(self.$number.column_name()),*]
73 }
74 fn headers(&self) -> Vec<Box<dyn Fn(&TableContext<Self>, Vec<Attribute>) -> Element + '_>> {
75 vec![$(Box::new(move |context, attributes| {
76 self.$number.render_header(context.data.column_context($number), attributes)
77 })),*]
78 }
79 fn columns(&self) -> Vec<Box<dyn Fn(&TableContext<Self>, &R, Vec<Attribute>) -> Element + '_>> {
80 vec![$(Box::new(move |context, row, attributes| {
81 self.$number.render_cell(context.data.column_context($number), row, attributes)
82 })),*]
83 }
84 fn filter(&self, row: &R) -> bool {
85 $(self.$number.filter(row) &&)* true
86 }
87 fn compare(&self) -> Vec<Box<dyn Fn(&R, &R) -> std::cmp::Ordering + '_>> {
88 vec![$(Box::new(move |a, b| self.$number.compare(a, b))),*]
89 }
90 }
91 #[cfg(feature = "export")]
92 serialize_columns!($($number => $column),*);
93 }
94}
95
96#[cfg(feature = "export")]
97macro_rules! serialize_columns {
98 ($($number:tt => $column:ident),*) => {
99 impl<$($column: crate::SerializableColumn<R>),*, R: Row> SerializableColumns<R> for ($($column),*,) {
100 fn serialize_headers(&self) -> Vec<Box<dyn Fn() -> String + '_>> {
101 vec![$(Box::new(move || self.$number.header())),*]
102 }
103 fn serialize_cell<Ex: Exporter>(&self) -> Vec<Box<dyn Fn(usize, usize, &R, &mut Ex) -> Result<(), Ex::Error> + '_>> {
104 vec![$(Box::new(move |row_index, col_index, row, exporter| exporter.serialize_cell(row_index, col_index, self.$number.serialize_cell(row)))),*]
105 }
106 }
107 }
108}
109
110columns!(0 => A);
111columns!(0 => A, 1 => B);
112columns!(0 => A, 1 => B, 2 => C);
113columns!(0 => A, 1 => B, 2 => C, 3 => D);
114columns!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E);
115columns!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F);
116columns!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G);
117columns!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H);
118columns!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I);
119columns!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J);
120columns!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J, 10 => K);
121columns!(0 => A, 1 => B, 2 => C, 3 => D, 4 => E, 5 => F, 6 => G, 7 => H, 8 => I, 9 => J, 10 => K, 11 => L);