rustyproxy/app/mods/
tables.rs

1#[macro_export]
2macro_rules! tbl_dyn_col {
3    ( $ui: expr, $closure: expr, $current_page: expr, $items_per_page: expr, $items_number: expr, $filter: expr, $filter_cat: expr, $filter_input: expr, $(($cols:expr, $active:expr)),*) => {
4        let mut tbl = TableBuilder::new($ui)
5            .auto_shrink([false, true])
6            .striped(true)
7            .cell_layout(egui::Layout::left_to_right(egui::Align::Center))
8            .resizable(true)
9            .vscroll(false)
10            .stick_to_bottom(false);
11        $(
12            if $active {
13                tbl = tbl.column($cols);
14            }
15        )*
16        tbl.body($closure);
17        $ui.separator();
18        egui::menu::bar($ui, |ui| {
19            if $items_number > $items_per_page {
20                let lbl = format!("Current page: {}", $current_page);
21                ui.label(lbl);
22                ui.label("⬌ Items per page: ");
23                ui.add(
24                    egui::Slider::new(
25                        &mut $items_per_page,
26                        (10 as usize)..=(40 as usize),
27                    )
28                    .logarithmic(true),
29                );
30            }
31
32            ui.separator();
33            ui.with_layout(egui::Layout::top_down(egui::Align::RIGHT), |ui| {
34                ui.horizontal(|ui| {
35                    if ui.button(">").clicked() {
36                        if $items_number - ($current_page * $items_per_page)
37                            > $items_per_page
38                        {
39                            $current_page += 1;
40                        }
41                    }
42                    if ui.button("<").clicked() {
43                        if $current_page != 0 {
44                            $current_page -= 1;
45                        }
46                    };
47                    ui.separator();
48                    ui.monospace($items_number.to_string());
49                    ui.label("Number of results: ");
50                    ui.separator();
51                });
52            });
53        });
54    };
55}
56
57#[macro_export]
58macro_rules! tbl_dyn_col_v2 {
59    ( $ui: expr, $closure: expr, $last_seen_idx:expr, $last_seen_idx_filtered: expr, $items_per_page: expr, $items_number: expr, $filter: expr, $filter_cat: expr, $filter_input: expr, $(($cols:expr, $active:expr, $headername: expr)),*) => {
60        let mut tbl = TableBuilder::new($ui)
61            .auto_shrink([false, true])
62            .striped(true)
63            .cell_layout(egui::Layout::left_to_right(egui::Align::Center))
64            .resizable(true)
65            .vscroll(false)
66            .stick_to_bottom(false);
67        $(
68            if $active {
69                tbl = tbl.column($cols);
70            }
71        )*
72        let tbl = tbl.header(20.0, |mut header| {
73                $(
74                    if $active {
75                        header.col(|ui| {
76                            ui.monospace($headername);
77                        });
78                    }
79                )*
80            });
81        tbl.body($closure);
82        $ui.separator();
83        egui::menu::bar($ui, |ui| {
84            if $items_number > $items_per_page {
85                let lbl = format!("Current range: {} - {}", $last_seen_idx, $last_seen_idx + $items_per_page);
86                ui.label(lbl);
87                ui.label("⬌ Items per page: ");
88                ui.add(
89                    egui::Slider::new(
90                        &mut $items_per_page,
91                        (10 as usize)..=(40 as usize),
92                    )
93                    .logarithmic(true),
94                );
95            }
96            ui.separator();
97            let menu = if $filter_cat.is_some(){
98                format!("Filter by: {:?}", $filter_cat.as_ref().unwrap())
99            }
100            else {
101                "Filter by ⏷".into()
102            };
103            ui.menu_button(menu, |ui| {
104                if ui.button("Host").clicked() {
105                    $filter_cat = Some(FilterCat::Host);
106                    $last_seen_idx = 0;
107                    $filter_input.clear();
108                    $filter = None;
109                }
110                if ui.button("Code").clicked() {
111                    $filter_cat = Some(FilterCat::Code);
112                    $last_seen_idx = 0;
113                    $filter_input.clear();
114                    $filter = None;
115                }
116                if ui.button("Source").clicked() {
117                    $filter_cat = Some(FilterCat::Source);
118                    $last_seen_idx = 0;
119                    $filter_input.clear();
120                    $filter = None;
121                }
122                if ui.button("Path").clicked() {
123                    $filter_cat = Some(FilterCat::Path);
124                    $last_seen_idx = 0;
125                    $filter_input.clear();
126                    $filter = None;
127                }
128                if ui.button("Generic").clicked() {
129                    $filter_cat = Some(FilterCat::Generic);
130                    $last_seen_idx = 0;
131                    $filter_input.clear();
132                    $filter = None;
133                }
134            });
135
136            let response = ui.text_edit_singleline($filter_input);
137            if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
138                if $filter_input != "" {
139                    $filter = Some($filter_input.to_owned());
140                } else {
141                    $filter = None;
142                }
143            }
144            ui.separator();
145            if ui.button("clear").clicked() {
146                $filter_input.clear();
147                $filter = None;
148            }
149            ui.separator();
150            ui.with_layout(egui::Layout::top_down(egui::Align::RIGHT), |ui| {
151                ui.horizontal(|ui| {
152                    if ui.button(">").clicked() {
153                        match $filter.is_some() {
154                            true => $last_seen_idx_filtered += $items_per_page,
155                            false => $last_seen_idx += $items_per_page,
156                        }
157                    }
158                    if ui.button("<").clicked() {
159                        match ($filter.is_some(), $last_seen_idx_filtered as i32 - $items_per_page as i32, $last_seen_idx as i32 - $items_per_page as i32) {
160                            (true, 0.., _) => $last_seen_idx_filtered -= $items_per_page, // $last_seen_idx_filtered >= $items_per_page
161                            (true, ..=-1, _) => $last_seen_idx_filtered = 0, // $last_seen_idx_filtered < $items_per_page
162                            (false, _, 0..) => $last_seen_idx -= $items_per_page, // $last_seen_idx >= $items_per_page
163                            (false, _, ..=-1) => $last_seen_idx = 0, // $last_seen_idx < $items_per_page
164                        }
165                    }
166                    ui.separator();
167                    ui.monospace($items_number.to_string());
168                    ui.label("Total (unfiltered): ");
169                    ui.separator();
170                });
171            });
172        });
173    };
174}
175
176#[macro_export]
177macro_rules! tbl_dyn_col_openapi {
178    ( $ui: expr, $closure: expr, $last_seen_idx:expr, $items_per_page: expr, $items_number: expr, $(($cols:expr, $headername: expr)),*) => {
179        let mut tbl = TableBuilder::new($ui)
180            .auto_shrink([false, true])
181            .striped(true)
182            .cell_layout(egui::Layout::left_to_right(egui::Align::Center))
183            .resizable(true)
184            .vscroll(true)
185            .stick_to_bottom(false);
186        $(
187            tbl = tbl.column($cols);
188        )*
189        let tbl = tbl.header(20.0, |mut header| {
190                $(
191                    header.col(|ui| {
192                        ui.monospace($headername);
193                    });
194                )*
195            });
196        tbl.body($closure);
197        $ui.separator();
198        $ui.with_layout(egui::Layout::top_down(egui::Align::RIGHT), |ui| {
199            ui.horizontal(|ui| {
200                if ui.button(">").clicked() {
201                        $last_seen_idx += $items_per_page;
202                }
203                if ui.button("<").clicked() {
204                    match ($last_seen_idx as i32 - $items_per_page as i32) {
205                        0.. => $last_seen_idx -= $items_per_page, // $last_seen_idx >= $items_per_page
206                        ..=-1 => $last_seen_idx = 0, // $last_seen_idx < $items_per_page
207                    }
208                }
209                ui.separator();
210                ui.monospace($items_number.to_string());
211                ui.label("Number of endpoints: ");
212                ui.separator();
213            });
214        });
215    };
216}
217
218#[macro_export]
219macro_rules! paginate {
220    ($current_page: expr, $items_per_page: expr, $items_number: expr) => {{
221        let mut range = Range {
222            start: $current_page * $items_per_page,
223            end: ($current_page + 1) * $items_per_page,
224        };
225
226        if range.end > $items_number {
227            range.end = $items_number;
228        }
229
230        if range.start > $items_number {
231            range.start = range.end - $items_per_page;
232            $current_page = range.start / $items_per_page;
233        }
234
235        range
236    }};
237}
238
239#[macro_export]
240macro_rules! row {
241    ($row: ident, $closure: expr, $(($cols:expr, $active:expr)),*) => {
242        $(
243            if $active {
244                $row.col(|ui|{
245                    if ui.add(egui::Label::new($cols).wrap(true).sense(egui::Sense::click())).clicked() {
246                        $closure;
247                    }
248                });
249            }
250
251        )*
252    }
253}
254
255#[macro_export]
256macro_rules! row_openapi {
257    ($row: ident, $(($cols:expr)),*) => {
258        $(
259            $row.col(|ui|{
260                ui.add(egui::Label::new($cols).wrap(true).sense(egui::Sense::click()));
261            });
262
263        )*
264    }
265}
266
267#[macro_export]
268macro_rules! filter {
269    ($item: expr, $filter: expr, $filter_cat: expr) => {
270        match ($filter, $filter_cat) {
271            (Some(f), Some(FilterCat::Host)) => $item.host().contains::<&str>(f),
272            (Some(f), Some(FilterCat::Code)) => $item.status() == f.parse::<usize>().unwrap(),
273            (Some(f), Some(FilterCat::Source)) => $item.remote_addr().contains::<&str>(f),
274            (Some(f), Some(FilterCat::Path)) => $item.uri().contains::<&str>(f),
275            (Some(f), Some(FilterCat::Generic)) => {
276                $item.raw().contains::<&str>(f) | $item.response().contains::<&str>(f)
277            }
278            (None, _) => true,
279            (Some(f), None) => $item.host().contains::<&str>(f),
280        }
281    };
282}