Skip to content

Commit a6c56fa

Browse files
Support for table styles
1 parent 2764a47 commit a6c56fa

File tree

4 files changed

+170
-16
lines changed

4 files changed

+170
-16
lines changed

CHANGELOG.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,34 @@
11
# rabbitmqadmin-ng Change Log
22

3-
## v0.23.0 (in development
3+
## v0.23.0 (in development)
44

5-
No (documented) changes yet.
5+
### Enhancements
6+
7+
* New general option `--table-style`, can be used to change output table styling.
8+
9+
For example, an equivalent of `--non-interactive` in terms of styling is
10+
11+
```shell
12+
rabbitmqadmin --table-style=borderless show overview
13+
```
14+
15+
More available styles:
16+
17+
```shell
18+
rabbitmqadmin --table-style=ascii show overview
19+
```
20+
21+
```shell
22+
rabbitmqadmin --table-style=psql show overview
23+
```
24+
25+
```shell
26+
rabbitmqadmin --table-style=markdown show overview
27+
```
28+
29+
```shell
30+
rabbitmqadmin --table-style=dots show overview
31+
```
632

733

834
## v0.22.0 (Feb 1, 2025)

src/cli.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use std::path::PathBuf;
1616
use super::constants::*;
1717
use super::static_urls::*;
1818
use super::tanzu_cli::tanzu_subcommands;
19+
use crate::output::TableStyle;
1920
use clap::{Arg, ArgAction, Command};
2021
use rabbitmq_http_client::commons::{
2122
BindingDestinationType, ExchangeType, QueueType, SupportedProtocol,
@@ -186,10 +187,20 @@ pub fn parser() -> Command {
186187
Arg::new("non_interactive")
187188
.long("non-interactive")
188189
.help("pass when invoking from scripts")
190+
.conflicts_with("table_style")
189191
.required(false)
190192
.value_parser(clap::value_parser!(bool))
191193
.action(ArgAction::SetTrue),
192194
)
195+
// --table-style
196+
.arg(
197+
Arg::new("table_style")
198+
.long("table-style")
199+
.help("style preset to apply to output tables: modern, borderless, ascii, dots, psql, markdown, sharp")
200+
.conflicts_with("non_interactive")
201+
.required(false)
202+
.value_parser(clap::value_parser!(TableStyle))
203+
)
193204
.subcommand_required(true)
194205
.subcommand_value_name("command")
195206
.subcommands([

src/config.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::constants::{
1616
DEFAULT_PASSWORD, DEFAULT_PATH_PREFIX, DEFAULT_SCHEME, DEFAULT_USERNAME, DEFAULT_VHOST,
1717
HTTPS_SCHEME,
1818
};
19+
use crate::output::TableStyle;
1920
use clap::ArgMatches;
2021
use serde::Deserialize;
2122
use std::collections::HashMap;
@@ -70,6 +71,9 @@ pub struct SharedSettings {
7071

7172
#[serde(skip_serializing_if = "Option::is_none")]
7273
pub virtual_host: Option<String>,
74+
75+
#[serde(skip_serializing_if = "Option::is_none")]
76+
pub table_style: Option<TableStyle>,
7377
}
7478

7579
impl SharedSettings {
@@ -164,6 +168,11 @@ impl SharedSettings {
164168
.cloned()
165169
.or(config_file_defaults.virtual_host.clone())
166170
.unwrap_or(DEFAULT_VHOST.to_owned());
171+
let table_style = cli_args
172+
.get_one::<TableStyle>("table_style")
173+
.cloned()
174+
.or(Some(TableStyle::default()))
175+
.unwrap_or(TableStyle::default());
167176

168177
Self {
169178
tls: should_use_tls,
@@ -177,6 +186,7 @@ impl SharedSettings {
177186
username: Some(username.to_string()),
178187
password: Some(password.to_string()),
179188
virtual_host: Some(vhost),
189+
table_style: Some(table_style),
180190
}
181191
}
182192

@@ -221,6 +231,11 @@ impl SharedSettings {
221231
.get_one::<String>("vhost")
222232
.cloned()
223233
.unwrap_or(DEFAULT_VHOST.to_owned());
234+
let table_style = cli_args
235+
.get_one::<TableStyle>("table_style")
236+
.cloned()
237+
.or(Some(TableStyle::default()))
238+
.unwrap_or(TableStyle::default());
224239

225240
Self {
226241
tls: should_use_tls,
@@ -234,6 +249,7 @@ impl SharedSettings {
234249
username: Some(username.to_string()),
235250
password: Some(password.to_string()),
236251
virtual_host: Some(vhost),
252+
table_style: Some(table_style),
237253
}
238254
}
239255

@@ -285,6 +301,11 @@ impl SharedSettings {
285301
.cloned()
286302
.or(config_file_defaults.virtual_host.clone())
287303
.unwrap_or(DEFAULT_VHOST.to_owned());
304+
let table_style = cli_args
305+
.get_one::<TableStyle>("table_style")
306+
.cloned()
307+
.or(Some(TableStyle::default()))
308+
.unwrap_or(TableStyle::default());
288309

289310
Self {
290311
tls: should_use_tls,
@@ -298,6 +319,7 @@ impl SharedSettings {
298319
username: Some(username),
299320
password: Some(password),
300321
virtual_host: Some(vhost),
322+
table_style: Some(table_style),
301323
}
302324
}
303325

@@ -341,6 +363,11 @@ impl SharedSettings {
341363
.get_one::<String>("vhost")
342364
.cloned()
343365
.unwrap_or(DEFAULT_VHOST.to_owned());
366+
let table_style = cli_args
367+
.get_one::<TableStyle>("table_style")
368+
.cloned()
369+
.or(Some(TableStyle::default()))
370+
.unwrap_or(TableStyle::default());
344371

345372
Self {
346373
tls: should_use_tls,
@@ -354,6 +381,7 @@ impl SharedSettings {
354381
username: Some(username),
355382
password: Some(password),
356383
virtual_host: Some(vhost),
384+
table_style: Some(table_style),
357385
}
358386
}
359387

src/output.rs

Lines changed: 103 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,59 +21,148 @@ use rabbitmq_http_client::responses::{
2121
NodeMemoryBreakdown, Overview, SchemaDefinitionSyncStatus, WarmStandbyReplicationStatus,
2222
};
2323
use reqwest::StatusCode;
24+
use serde::{Deserialize, Serialize};
2425
use std::fmt;
2526
use sysexits::ExitCode;
2627
use tabled::settings::object::Rows;
2728
use tabled::settings::{Panel, Remove, Style};
2829
use tabled::{Table, Tabled};
2930

31+
#[derive(Default, Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Copy)]
32+
pub enum TableStyle {
33+
#[default]
34+
Modern,
35+
Borderless,
36+
Markdown,
37+
Sharp,
38+
Ascii,
39+
Psql,
40+
Dots,
41+
}
42+
43+
impl From<&str> for TableStyle {
44+
fn from(s: &str) -> Self {
45+
match s {
46+
"modern" => TableStyle::Modern,
47+
"borderless" => TableStyle::Borderless,
48+
"ascii" => TableStyle::Ascii,
49+
"markdown" => TableStyle::Markdown,
50+
"sharp" => TableStyle::Sharp,
51+
"psql" => TableStyle::Psql,
52+
"dots" => TableStyle::Dots,
53+
_ => TableStyle::default(),
54+
}
55+
}
56+
}
57+
58+
impl From<String> for TableStyle {
59+
fn from(value: String) -> Self {
60+
TableStyle::from(value.as_str())
61+
}
62+
}
63+
3064
#[derive(Copy, Clone)]
3165
pub struct TableStyler {
32-
non_interactive: bool,
66+
pub style: TableStyle,
3367
}
3468

3569
impl TableStyler {
3670
pub fn new(args: &SharedSettings) -> Self {
37-
let non_interactive = args.non_interactive;
71+
if args.non_interactive {
72+
return Self {
73+
style: TableStyle::Borderless,
74+
};
75+
};
3876

39-
Self { non_interactive }
77+
Self {
78+
style: args.table_style.unwrap_or_default(),
79+
}
4080
}
4181

4282
pub fn apply(self, table: &mut Table) {
43-
if self.non_interactive {
44-
table.with(Style::empty());
45-
table.with(Remove::row(Rows::first()));
46-
} else {
47-
table.with(Style::modern());
83+
match self.style {
84+
TableStyle::Modern => {
85+
self.apply_modern(table);
86+
}
87+
TableStyle::Borderless => {
88+
self.apply_borderless(table);
89+
}
90+
TableStyle::Markdown => {
91+
self.apply_markdown(table);
92+
}
93+
TableStyle::Sharp => {
94+
self.apply_sharp(table);
95+
}
96+
TableStyle::Ascii => {
97+
self.apply_ascii(table);
98+
}
99+
TableStyle::Psql => {
100+
self.apply_psql(table);
101+
}
102+
TableStyle::Dots => {
103+
self.apply_dots(table);
104+
}
48105
}
49106
}
107+
108+
fn apply_modern(self, table: &mut Table) -> &Table {
109+
table.with(Style::modern())
110+
}
111+
112+
fn apply_borderless(self, table: &mut Table) -> &Table {
113+
table.with(Style::empty());
114+
table.with(Remove::row(Rows::first()))
115+
}
116+
117+
fn apply_markdown(self, table: &mut Table) -> &Table {
118+
table.with(Style::markdown())
119+
}
120+
121+
fn apply_sharp(self, table: &mut Table) -> &Table {
122+
table.with(Style::sharp())
123+
}
124+
125+
fn apply_psql(self, table: &mut Table) -> &Table {
126+
table.with(Style::psql())
127+
}
128+
129+
fn apply_dots(self, table: &mut Table) -> &Table {
130+
table.with(Style::dots())
131+
}
132+
133+
fn apply_ascii(self, table: &mut Table) -> &Table {
134+
table.with(Style::ascii())
135+
}
50136
}
51137

52138
#[allow(dead_code)]
53-
pub struct ResultHandler {
139+
pub struct ResultHandler<'a> {
140+
cli_args: &'a SharedSettings,
141+
table_styler: TableStyler,
54142
pub non_interactive: bool,
55143
pub quiet: bool,
56144
pub idempotently: bool,
57145
pub exit_code: Option<ExitCode>,
58-
table_styler: TableStyler,
59146
}
60147

61-
impl ResultHandler {
62-
pub fn new(common_args: &SharedSettings, command_args: &ArgMatches) -> Self {
148+
impl<'a> ResultHandler<'a> {
149+
pub fn new(common_args: &'a SharedSettings, command_args: &ArgMatches) -> Self {
63150
let non_interactive = common_args.non_interactive;
64151
let quiet = common_args.quiet;
65152
let idempotently = match command_args.try_get_one::<bool>("idempotently") {
66153
Ok(val) => val.cloned().unwrap_or(false),
67154
Err(_) => false,
68155
};
69-
let table_formatter = TableStyler::new(common_args);
156+
157+
let table_styler = TableStyler::new(common_args);
70158

71159
Self {
160+
cli_args: common_args,
161+
table_styler,
72162
quiet,
73163
non_interactive,
74164
idempotently,
75165
exit_code: None,
76-
table_styler: table_formatter,
77166
}
78167
}
79168

0 commit comments

Comments
 (0)