phink_lib/cli/ui/
configtable.rs1use crate::cli::{
2 config::Configuration,
3 ui,
4 ui::traits::Paint,
5};
6use ratatui::{
7 layout::{
8 Constraint,
9 Rect,
10 },
11 prelude::{
12 Alignment,
13 Color,
14 Modifier,
15 Style,
16 Stylize,
17 },
18 style::palette::{
19 tailwind,
20 tailwind::Palette,
21 },
22 widgets::{
23 Block,
24 Borders,
25 HighlightSpacing,
26 Row,
27 Table,
28 },
29 Frame,
30};
31use ui::ratatui::CTOR_VALUE;
32
33const PALETTE: Palette = tailwind::RED;
34struct TableColors {
35 buffer_bg: Color,
36 header_bg: Color,
37 header_fg: Color,
38 row_fg: Color,
39 selected_style_fg: Color,
40 normal_row_color: Color,
41 alt_row_color: Color,
42}
43
44impl TableColors {
45 const fn new(color: &Palette) -> Self {
46 Self {
47 buffer_bg: tailwind::SLATE.c950,
48 header_bg: color.c900,
49 header_fg: tailwind::SLATE.c200,
50 row_fg: tailwind::SLATE.c200,
51 selected_style_fg: color.c400,
52 normal_row_color: tailwind::SLATE.c950,
53 alt_row_color: tailwind::SLATE.c900,
54 }
55 }
56}
57
58impl Paint for Configuration {
59 fn render(&self, f: &mut Frame, area: Rect) {
60 fn format_option<T: std::fmt::Debug>(option: &Option<T>) -> String {
62 match option {
63 Some(value) => {
64 format!("{:?}", value)
65 .trim_matches(|c| c == '"' || c == '(' || c == ')')
66 .to_string()
67 }
68 None => "-".to_string(),
69 }
70 }
71
72 let colors = TableColors::new(&PALETTE);
73
74 let x = &format_option(&self.instantiate_initial_value);
75 let x1 = &format_option(&self.cores);
76 let x2 = &self.use_honggfuzz.to_string();
77 let x3 = &format_option(&self.deployer_address);
78 let x4 = &format_option(&self.max_messages_per_exec);
79 let x5 = &format_option(&self.report_path);
80 let x6 = &self.fuzz_origin.to_string();
81 let x7 = format!(
82 "ref_time = {} proof_size = {}",
83 &self.default_gas_limit.unwrap_or_default().ref_time(),
84 &self.default_gas_limit.unwrap_or_default().proof_size()
85 );
86 let x8 = &format_option(&self.storage_deposit_limit);
87 let x9 = CTOR_VALUE.get().unwrap().to_string();
88
89 let x10 = &self.verbose.to_string();
90 let ctr = &self.instrumented_contract();
91 let x11 = ctr.to_str().unwrap();
92 let x12 = &format_option(&self.fuzz_output);
93 let x13 = &self.show_ui.to_string();
94 let items = vec![
95 Row::new(vec!["Cores used", x1]),
96 Row::new(vec!["Using Honggfuzz", x2]),
97 Row::new(vec!["Deployer address", x3]),
98 Row::new(vec!["Max messages per exec", x4]),
99 Row::new(vec!["Report path", x5]),
100 Row::new(vec!["Fuzzing origin", x6]),
101 Row::new(vec!["Default gas limit", &x7]),
102 Row::new(vec!["Storage deposit limit", x8]),
103 Row::new(vec!["Instantiate initial value", x]),
104 Row::new(vec!["Constructor payload", &x9]),
105 Row::new(vec!["Verbose mode", x10]),
106 Row::new(vec!["Path to instrumented contract", x11]),
107 Row::new(vec!["Fuzz output folder", x12]),
108 Row::new(vec!["Custom UI", x13]),
109 ];
110
111 let rows = items.iter().enumerate().map(|(i, row)| {
112 let color = match i % 2 {
113 0 => colors.normal_row_color,
114 _ => colors.alt_row_color,
115 };
116 row.clone()
117 .style(Style::new().fg(colors.row_fg).bg(color))
118 .height(1)
119 });
120
121 let selected_style = Style::default()
122 .add_modifier(Modifier::REVERSED)
123 .fg(colors.selected_style_fg);
124 let header_style = Style::default()
125 .fg(colors.header_fg)
126 .bg(colors.header_bg)
127 .bold();
128
129 let table = Table::new(
130 rows,
131 [Constraint::Percentage(50), Constraint::Percentage(50)],
132 )
133 .header(Row::new(vec!["Setting", "Value"]).style(header_style))
134 .block(
135 Block::default()
136 .borders(Borders::ALL)
137 .title("Configuration (phink.toml)")
138 .bold()
139 .title_alignment(Alignment::Center),
140 )
141 .row_highlight_style(selected_style)
142 .widths([Constraint::Percentage(25), Constraint::Percentage(75)])
143 .column_spacing(1)
144 .row_highlight_style(Style::default().add_modifier(Modifier::BOLD))
145 .highlight_symbol("> ")
146 .bg(colors.buffer_bg)
147 .highlight_spacing(HighlightSpacing::Always);
148
149 f.render_widget(table, area);
150 }
151}