Skip to main content

tree_table/types/
opts.rs

1use crate::Color3;
2use crate::Table;
3use crate::Val;
4use crate::utils::utils_fns::generate_unique_id;
5use alloc::string::String;
6use alloc::string::ToString;
7
8macro_rules! define_options {
9    ($($field:ident: $ty:ty, $default_str:literal => $default:expr),* $(,)?) => {
10        #[cfg_attr(feature = "tsify", derive(tsify::Tsify))]
11        #[cfg_attr(feature = "tsify", tsify(from_wasm_abi))]
12        #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13        #[derive(Debug, Clone, PartialEq)]
14        pub struct Options {
15            $(
16                pub $field: $ty
17            ),*
18        }
19        #[cfg_attr(feature = "tsify", derive(tsify::Tsify))]
20        #[cfg_attr(feature = "tsify", tsify(from_wasm_abi))]
21        #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22        #[derive(Debug, Clone, PartialEq)]
23        pub struct PartialOptions {
24            $(
25                pub $field: Option<$ty>
26            ),*
27        }
28        $(
29            pub fn $field() -> $ty { $default }
30        )*
31
32        impl Default for Options {
33            fn default() -> Self {
34                Self {
35                    $(
36                        $field: $default,
37                    )*
38                }
39            }
40        }
41
42        impl Default for PartialOptions {
43            fn default() -> Self {
44                Self {
45                    $(
46                        $field: None,
47                    )*
48                }
49            }
50        }
51
52        impl PartialOptions {
53            pub fn with_defaults() -> Self {
54                Self {
55                    $(
56                        $field: Some($field()),
57                    )*
58                }
59            }
60        }
61
62        macro_rules! merge_self_opts_fields {
63            ($self:expr, $partial:ident) => {
64                $(
65                    if let Some(val) = $partial.$field {
66                        $self.opts.$field = val;
67                    }
68                )*
69            }
70        }
71
72        macro_rules! merge_opts_fields {
73            ($opts:expr, $partial:ident) => {
74                $(
75                    if let Some(val) = $partial.$field {
76                        $opts.$field = val;
77                    }
78                )*
79            }
80        }
81    };
82}
83
84define_options! {
85    // General
86    widget_name: String, "widget_name" => "!table".to_string(),
87    widget_id: u32, "widget_id" => generate_unique_id(),
88    tree_mode: bool, "tree_mode" => false,
89    tree_indent: u64, "tree_indent" => 2,
90    empty_val: Val, "empty_val" => Val::Nil(()),
91    empty_index_val: Val, "empty_index_val" => Val::Nil(()),
92    empty_header_val: Val, "empty_header_val" => Val::Nil(()),
93    max_undos: usize, "max_undos" => 50,
94    default_row_dim: u64, "default_row_dim" => 40,
95    default_col_dim: u64, "default_col_dim" => 150,
96    min_row_dim: u64, "min_row_dim" => 1,
97    min_col_dim: u64, "min_col_dim" => 1,
98    max_row_dim: u64, "max_row_dim" => u64::MAX,
99    max_col_dim: u64, "max_col_dim" => u64::MAX,
100    paste_expands_y: bool, "paste_expands_y" => false,
101    paste_expands_x: bool, "paste_expands_x" => false,
102    paste_max_rows: Option<u64>, "paste_max_rows" => None,
103    paste_max_cols: Option<u64>, "paste_max_cols" => None,
104    csv_out_delimiter: String, "csv_out_delimiter" => "\t".to_string(),
105    csv_out_quotechar: String, "csv_out_quotechar" => '"'.to_string(),
106    csv_out_lineterminator: String, "csv_out_lineterminator" => "\n".to_string(),
107    empty_horizontal: u64, "empty_horizontal" => 50,
108    empty_vertical: u64, "empty_vertical" => 50,
109    show_horizontal_grid: bool, "show_horizontal_grid" => true,
110    show_vertical_grid: bool, "show_vertical_grid" => true,
111    table_wrap: String, "table_wrap" => "c".to_string(),
112    index_wrap: String, "index_wrap" => "c".to_string(),
113    header_wrap: String, "header_wrap" => "c".to_string(),
114
115    // Data formatting default invalid values to display
116    invalid_display_un8:   String, "invalid_display_un8"   => "NaN".to_string(),
117    invalid_display_un16:  String, "invalid_display_un16"  => "NaN".to_string(),
118    invalid_display_un32:  String, "invalid_display_un32"  => "NaN".to_string(),
119    invalid_display_un64:  String, "invalid_display_un64"  => "NaN".to_string(),
120    invalid_display_un128: String, "invalid_display_un128" => "NaN".to_string(),
121
122    invalid_display_sn8:   String, "invalid_display_sn8"   => "NaN".to_string(),
123    invalid_display_sn16:  String, "invalid_display_sn16"  => "NaN".to_string(),
124    invalid_display_sn32:  String, "invalid_display_sn32"  => "NaN".to_string(),
125    invalid_display_sn64:  String, "invalid_display_sn64"  => "NaN".to_string(),
126    invalid_display_sn128: String, "invalid_display_sn128" => "NaN".to_string(),
127
128    invalid_display_fl64:  String, "invalid_display_fl64"  => "NaN".to_string(),
129    invalid_display_bigint:String, "invalid_display_bigint"=> "NaN".to_string(),
130    invalid_display_bigdec:String, "invalid_display_bigdec"=> "NaN".to_string(),
131    invalid_display_dec:   String, "invalid_display_dec"   => "NaN".to_string(),
132
133    invalid_display_str:   String, "invalid_display_str"   => "Invalid".to_string(),
134    invalid_display_chr:   String, "invalid_display_chr"   => "?".to_string(),
135    invalid_display_bl:    String, "invalid_display_bl"    => "Invalid".to_string(),
136    invalid_display_nil:   String, "invalid_display_nil"   => "Invalid".to_string(),
137    invalid_display_undf:  String, "invalid_display_undf" => "Invalid".to_string(),
138    invalid_display_dt:    String, "invalid_display_dt"    => "Invalid Date".to_string(),
139    invalid_display_dur:   String, "invalid_display_dur"   => "Invalid Duration".to_string(),
140
141    // Enabled Functionality
142    enabled_undo: bool, "enabled_undo" => false,
143    validation_includes_undo: bool, "validation_includes_undo" => false,
144
145    // Appearance
146    horizontal_grid_line_width: u64, "horizontal_grid_line_width" => 1,
147    vertical_grid_line_width: u64, "vertical_grid_line_width" => 1,
148    show_row_numbering: String, "show_row_numbering" => "numbers".to_string(),
149    show_col_numbering: String, "show_col_numbering" => "letters".to_string(),
150    show_index: bool, "show_index" => true,
151    show_header: bool, "show_header" => true,
152    popup_menu_fg: Color3, "popup_menu_fg" => Color3 {r: 0, g: 0, b: 0},
153    popup_menu_bg: Color3, "popup_menu_bg" => Color3 {r: 255, g: 255, b: 255},
154    popup_menu_highlight_bg: Color3, "popup_menu_highlight_bg" => Color3 {r: 220, g: 222, b: 224},
155    popup_menu_highlight_fg: Color3, "popup_menu_highlight_fg" => Color3 {r: 0, g: 0, b: 0},
156    index_hidden_rows_expander_bg: Color3, "index_hidden_rows_expander_bg" => Color3 {r: 116, g: 119, b: 117},
157    header_hidden_cols_expander_bg: Color3, "header_hidden_cols_expander_bg" => Color3 {r: 116, g: 119, b: 117},
158    header_bg: Color3, "header_bg" => Color3 {r: 255, g: 255, b: 255},
159    header_border_fg: Color3, "header_border_fg" => Color3 {r: 196, g: 199, b: 197},
160    header_grid_fg: Color3, "header_grid_fg" => Color3 {r: 196, g: 199, b: 197},
161    header_fg: Color3, "header_fg" => Color3 {r: 68, g: 71, b: 70},
162    header_editor_bg: Color3, "header_editor_bg" => Color3 {r: 255, g: 255, b: 255},
163    header_editor_fg: Color3, "header_editor_fg" => Color3 {r: 68, g: 71, b: 70},
164    header_editor_select_bg: Color3, "header_editor_select_bg" => Color3 {r: 207, g: 209, b: 209},
165    header_editor_select_fg: Color3, "header_editor_select_fg" => Color3 {r: 0, g: 0, b: 0},
166    header_selected_cells_bg: Color3, "header_selected_cells_bg" => Color3 {r: 211, g: 227, b: 253},
167    header_selected_cells_fg: Color3, "header_selected_cells_fg" => Color3 {r: 0, g: 0, b: 0},
168    index_bg: Color3, "index_bg" => Color3 {r: 255, g: 255, b: 255},
169    index_border_fg: Color3, "index_border_fg" => Color3 {r: 196, g: 199, b: 197},
170    index_grid_fg: Color3, "index_grid_fg" => Color3 {r: 196, g: 199, b: 197},
171    index_fg: Color3, "index_fg" => Color3 {r: 0, g: 0, b: 0},
172    index_editor_bg: Color3, "index_editor_bg" => Color3 {r: 255, g: 255, b: 255},
173    index_editor_fg: Color3, "index_editor_fg" => Color3 {r: 0, g: 0, b: 0},
174    index_editor_select_bg: Color3, "index_editor_select_bg" => Color3 {r: 207, g: 209, b: 209},
175    index_editor_select_fg: Color3, "index_editor_select_fg" => Color3 {r: 0, g: 0, b: 0},
176    index_selected_cells_bg: Color3, "index_selected_cells_bg" => Color3 {r: 211, g: 227, b: 253},
177    index_selected_cells_fg: Color3, "index_selected_cells_fg" => Color3 {r: 0, g: 0, b: 0},
178    top_left_bg: Color3, "top_left_bg" => Color3 {r: 249, g: 251, b: 253},
179    top_left_fg: Color3, "top_left_fg" => Color3 {r: 217, g: 217, b: 217},
180    top_left_fg_highlight: Color3, "top_left_fg_highlight" => Color3 {r: 116, g: 119, b: 117},
181    table_bg: Color3, "table_bg" => Color3 {r: 255, g: 255, b: 255},
182    table_grid_fg: Color3, "table_grid_fg" => Color3 {r: 225, g: 225, b: 225},
183    table_fg: Color3, "table_fg" => Color3 {r: 0, g: 0, b: 0},
184    table_editor_bg: Color3, "table_editor_bg" => Color3 {r: 255, g: 255, b: 255},
185    table_editor_fg: Color3, "table_editor_fg" => Color3 {r: 0, g: 0, b: 0},
186    table_editor_select_bg: Color3, "table_editor_select_bg" => Color3 {r: 207, g: 209, b: 209},
187    table_editor_select_fg: Color3, "table_editor_select_fg" => Color3 {r: 0, g: 0, b: 0},
188    table_selected_box_cells_fg: Color3, "table_selected_box_cells_fg" => Color3 {r: 11, g: 87, b: 208},
189    table_selected_box_rows_fg: Color3, "table_selected_box_rows_fg" => Color3 {r: 11, g: 87, b: 208},
190    table_selected_box_cols_fg: Color3, "table_selected_box_cols_fg" => Color3 {r: 11, g: 87, b: 208},
191    table_selected_cells_border_fg: Color3, "table_selected_cells_border_fg" => Color3 {r: 11, g: 87, b: 208},
192    table_selected_cells_bg: Color3, "table_selected_cells_bg" => Color3 {r: 230, g: 239, b: 253},
193    table_selected_cells_fg: Color3, "table_selected_cells_fg" => Color3 {r: 0, g: 0, b: 0},
194    resizing_line_fg: Color3, "resizing_line_fg" => Color3 {r: 0, g: 0, b: 0},
195    drag_and_drop_bg: Color3, "drag_and_drop_bg" => Color3 {r: 11, g: 87, b: 208},
196    header_selected_cols_bg: Color3, "header_selected_cols_bg" => Color3 {r: 11, g: 87, b: 208},
197    header_selected_cols_fg: Color3, "header_selected_cols_fg" => Color3 {r: 255, g: 255, b: 255},
198    index_selected_rows_bg: Color3, "index_selected_rows_bg" => Color3 {r: 11, g: 87, b: 208},
199    index_selected_rows_fg: Color3, "index_selected_rows_fg" => Color3 {r: 255, g: 255, b: 255},
200    table_selected_rows_border_fg: Color3, "table_selected_rows_border_fg" => Color3 {r: 11, g: 87, b: 208},
201    table_selected_rows_bg: Color3, "table_selected_rows_bg" => Color3 {r: 230, g: 239, b: 253},
202    table_selected_rows_fg: Color3, "table_selected_rows_fg" => Color3 {r: 0, g: 0, b: 0},
203    table_selected_cols_border_fg: Color3, "table_selected_cols_border_fg" => Color3 {r: 11, g: 87, b: 208},
204    table_selected_cols_bg: Color3, "table_selected_cols_bg" => Color3 {r: 230, g: 239, b: 253},
205    table_selected_cols_fg: Color3, "table_selected_cols_fg" => Color3 {r: 0, g: 0, b: 0},
206    tree_arrow_fg: Color3, "tree_arrow_fg" => Color3 {r: 0, g: 0, b: 0},
207    selected_cells_tree_arrow_fg: Color3, "selected_cells_tree_arrow_fg" => Color3 {r: 0, g: 0, b: 0},
208    selected_rows_tree_arrow_fg: Color3, "selected_rows_tree_arrow_fg" => Color3 {r: 255, g: 255, b: 255},
209}
210
211impl Table {
212    pub fn acr_validate_partial_opts(partial: &mut PartialOptions) -> Result<(), String> {
213        // TODO: Check the incoming settings are valid. Perhaps return Err if not?
214        Ok(())
215    }
216
217    /// Validates input before applying settings changes to table.
218    pub fn cr_merge_opts(&mut self, mut partial: PartialOptions) -> Result<(), String> {
219        Self::acr_validate_partial_opts(&mut partial)?;
220        merge_self_opts_fields!(self, partial);
221        Ok(())
222    }
223}
224
225impl Options {
226    pub fn new() -> Self {
227        Self::default()
228    }
229
230    pub fn merge(mut merge_into: Options, merge_using: PartialOptions) -> Options {
231        merge_opts_fields!(merge_into, merge_using);
232        merge_into
233    }
234}
235
236impl PartialOptions {
237    pub fn new() -> Self {
238        Self::default()
239    }
240}