1+ use comfy_table:: Color ;
2+ use comfy_table:: ContentArrangement ;
3+ use gitql_core:: object:: GitQLObject ;
14use gitql_core:: object:: Row ;
25
36use super :: BaseOutputPrinter ;
@@ -11,19 +14,41 @@ enum PaginationInput {
1114pub 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
1636impl 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
2550impl 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