Skip to content

Commit bc5bf99

Browse files
committed
Allow customiztion in Table Printer component
1 parent 6911ee1 commit bc5bf99

1 file changed

Lines changed: 109 additions & 62 deletions

File tree

Lines changed: 109 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use comfy_table::Color;
2+
use comfy_table::ContentArrangement;
3+
use gitql_core::object::GitQLObject;
14
use gitql_core::object::Row;
25

36
use super::BaseOutputPrinter;
@@ -11,19 +14,41 @@ enum PaginationInput {
1114
pub struct TablePrinter {
1215
pub pagination: bool,
1316
pub page_size: usize,
17+
pub theme_config: TableThemeConfig,
18+
}
19+
20+
pub struct TableThemeConfig {
21+
pub header_forground_color: Option<Color>,
22+
pub header_background_color: Option<Color>,
23+
pub arrangement: Option<ContentArrangement>,
24+
}
25+
26+
impl Default for TableThemeConfig {
27+
fn default() -> TableThemeConfig {
28+
TableThemeConfig {
29+
header_forground_color: Some(Color::Green),
30+
header_background_color: None,
31+
arrangement: Some(comfy_table::ContentArrangement::Dynamic),
32+
}
33+
}
1434
}
1535

1636
impl TablePrinter {
1737
pub fn new(pagination: bool, page_size: usize) -> Self {
1838
TablePrinter {
1939
pagination,
2040
page_size,
41+
theme_config: TableThemeConfig::default(),
2142
}
2243
}
44+
45+
pub fn set_theme(&mut self, theme: TableThemeConfig) {
46+
self.theme_config = theme;
47+
}
2348
}
2449

2550
impl BaseOutputPrinter for TablePrinter {
26-
fn print(&self, object: &mut gitql_core::object::GitQLObject) {
51+
fn print(&self, object: &mut GitQLObject) {
2752
if object.is_empty() || object.groups[0].is_empty() {
2853
return;
2954
}
@@ -33,15 +58,23 @@ impl BaseOutputPrinter for TablePrinter {
3358
let group_len = group.len();
3459

3560
// Setup table headers
36-
let header_color = comfy_table::Color::Green;
3761
let mut table_headers = vec![];
3862
for key in titles {
39-
table_headers.push(comfy_table::Cell::new(key).fg(header_color));
63+
let mut table_cell = comfy_table::Cell::new(key);
64+
if let Some(forground_color) = self.theme_config.header_forground_color {
65+
table_cell = table_cell.fg(forground_color);
66+
}
67+
68+
if let Some(background_color) = self.theme_config.header_background_color {
69+
table_cell = table_cell.bg(background_color);
70+
}
71+
72+
table_headers.push(table_cell);
4073
}
4174

4275
// Print all data without pagination
4376
if !self.pagination || self.page_size >= group_len {
44-
print_group_as_table(titles, table_headers, &group.rows);
77+
self.print_group_as_table(titles, table_headers, &group.rows);
4578
return;
4679
}
4780

@@ -55,9 +88,9 @@ impl BaseOutputPrinter for TablePrinter {
5588

5689
let current_page_groups = &group.rows[start_index..end_index];
5790
println!("Page {}/{}", current_page, number_of_pages);
58-
print_group_as_table(titles, table_headers.clone(), current_page_groups);
91+
self.print_group_as_table(titles, table_headers.clone(), current_page_groups);
5992

60-
let pagination_input = handle_pagination_input(current_page, number_of_pages);
93+
let pagination_input = self.handle_pagination_input(current_page, number_of_pages);
6194
match pagination_input {
6295
PaginationInput::NextPage => current_page += 1,
6396
PaginationInput::PreviousPage => current_page -= 1,
@@ -67,74 +100,88 @@ impl BaseOutputPrinter for TablePrinter {
67100
}
68101
}
69102

70-
fn print_group_as_table(titles: &[String], table_headers: Vec<comfy_table::Cell>, rows: &[Row]) {
71-
let mut table = comfy_table::Table::new();
72-
73-
// Setup table style
74-
table.load_preset(comfy_table::presets::UTF8_FULL);
75-
table.apply_modifier(comfy_table::modifiers::UTF8_ROUND_CORNERS);
76-
table.set_content_arrangement(comfy_table::ContentArrangement::Dynamic);
103+
impl TablePrinter {
104+
fn print_group_as_table(
105+
&self,
106+
titles: &[String],
107+
table_headers: Vec<comfy_table::Cell>,
108+
rows: &[Row],
109+
) {
110+
let mut table = comfy_table::Table::new();
111+
112+
// Setup table style
113+
table.load_preset(comfy_table::presets::UTF8_FULL);
114+
table.apply_modifier(comfy_table::modifiers::UTF8_ROUND_CORNERS);
115+
116+
if let Some(arrangement) = &self.theme_config.arrangement {
117+
table.set_content_arrangement(arrangement.clone());
118+
}
77119

78-
table.set_header(table_headers);
120+
table.set_header(table_headers);
79121

80-
let titles_len = titles.len();
122+
let titles_len = titles.len();
81123

82-
// Add rows to the table
83-
for row in rows {
84-
let mut table_row: Vec<comfy_table::Cell> = vec![];
85-
for index in 0..titles_len {
86-
if let Some(value) = row.values.get(index) {
87-
table_row.push(comfy_table::Cell::new(value.literal()));
124+
// Add rows to the table
125+
for row in rows {
126+
let mut table_row: Vec<comfy_table::Cell> = vec![];
127+
for index in 0..titles_len {
128+
if let Some(value) = row.values.get(index) {
129+
table_row.push(comfy_table::Cell::new(value.literal()));
130+
}
88131
}
132+
table.add_row(table_row);
89133
}
90-
table.add_row(table_row);
91-
}
92134

93-
// Print table
94-
println!("{table}");
95-
}
135+
// Print table
136+
println!("{table}");
137+
}
96138

97-
fn handle_pagination_input(current_page: usize, number_of_pages: usize) -> PaginationInput {
98-
loop {
99-
if current_page < 2 {
100-
println!("Enter 'n' for next page, or 'q' to quit:");
101-
} else if current_page == number_of_pages {
102-
println!("'p' for previous page, or 'q' to quit:");
103-
} else {
104-
println!("Enter 'n' for next page, 'p' for previous page, or 'q' to quit:");
105-
}
139+
fn handle_pagination_input(
140+
&self,
141+
current_page: usize,
142+
number_of_pages: usize,
143+
) -> PaginationInput {
144+
loop {
145+
if current_page < 2 {
146+
println!("Enter 'n' for next page, or 'q' to quit:");
147+
} else if current_page == number_of_pages {
148+
println!("'p' for previous page, or 'q' to quit:");
149+
} else {
150+
println!("Enter 'n' for next page, 'p' for previous page, or 'q' to quit:");
151+
}
106152

107-
std::io::Write::flush(&mut std::io::stdout()).expect("flush failed!");
108-
109-
let mut line = String::new();
110-
std::io::stdin()
111-
.read_line(&mut line)
112-
.expect("Failed to read input");
113-
114-
let input = line.trim();
115-
if input == "q" || input == "n" || input == "p" {
116-
match input {
117-
"n" => {
118-
if current_page < number_of_pages {
119-
return PaginationInput::NextPage;
120-
} else {
121-
println!("Already on the last page");
122-
continue;
153+
std::io::Write::flush(&mut std::io::stdout()).expect("flush failed!");
154+
155+
let mut line = String::new();
156+
std::io::stdin()
157+
.read_line(&mut line)
158+
.expect("Failed to read input");
159+
160+
let input = line.trim();
161+
if input == "q" || input == "n" || input == "p" {
162+
match input {
163+
"n" => {
164+
if current_page < number_of_pages {
165+
return PaginationInput::NextPage;
166+
} else {
167+
println!("Already on the last page");
168+
continue;
169+
}
123170
}
124-
}
125-
"p" => {
126-
if current_page > 1 {
127-
return PaginationInput::PreviousPage;
128-
} else {
129-
println!("Already on the first page");
130-
continue;
171+
"p" => {
172+
if current_page > 1 {
173+
return PaginationInput::PreviousPage;
174+
} else {
175+
println!("Already on the first page");
176+
continue;
177+
}
131178
}
179+
"q" => return PaginationInput::Quit,
180+
_ => unreachable!(),
132181
}
133-
"q" => return PaginationInput::Quit,
134-
_ => unreachable!(),
135182
}
136-
}
137183

138-
println!("Invalid input");
184+
println!("Invalid input");
185+
}
139186
}
140187
}

0 commit comments

Comments
 (0)