Skip to content

Commit 8b2549d

Browse files
committed
Add customize_fn attribute in derive macro and add styling information in readme
1 parent 10e9478 commit 8b2549d

File tree

6 files changed

+127
-4
lines changed

6 files changed

+127
-4
lines changed

cli-table-derive/src/context/fields.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pub struct Field {
5252
pub bold: Option<LitBool>,
5353
pub order: usize,
5454
pub display_fn: Option<Ident>,
55+
pub customize_fn: Option<Ident>,
5556
pub span: Span,
5657
}
5758

@@ -71,6 +72,7 @@ impl Field {
7172
let mut bold = None;
7273
let mut order = None;
7374
let mut display_fn = None;
75+
let mut customize_fn = None;
7476
let mut skip = None;
7577

7678
let field_attributes = get_attributes(&field.attrs)?;
@@ -129,6 +131,14 @@ impl Field {
129131
"Invalid value for #[table(display_fn = \"value\")]",
130132
)),
131133
}?);
134+
} else if key.is_ident("customize_fn") {
135+
customize_fn = Some(match value {
136+
Lit::Str(lit_str) => lit_str.parse::<Ident>(),
137+
bad => Err(Error::new_spanned(
138+
bad,
139+
"Invalid value for #[table(display_fn = \"value\")]",
140+
)),
141+
}?);
132142
} else if key.is_ident("skip") {
133143
skip = Some(match value {
134144
Lit::Bool(lit_bool) => Ok(lit_bool),
@@ -173,6 +183,10 @@ impl Field {
173183
field_builder.display_fn(display_fn);
174184
}
175185

186+
if let Some(customize_fn) = customize_fn {
187+
field_builder.customize_fn(customize_fn);
188+
}
189+
176190
Ok(Some(field_builder.build()))
177191
}
178192

@@ -190,6 +204,7 @@ struct FieldBuilder {
190204
bold: Option<LitBool>,
191205
order: Option<usize>,
192206
display_fn: Option<Ident>,
207+
customize_fn: Option<Ident>,
193208
span: Span,
194209
}
195210

@@ -204,6 +219,7 @@ impl FieldBuilder {
204219
bold: None,
205220
order: None,
206221
display_fn: None,
222+
customize_fn: None,
207223
span,
208224
}
209225
}
@@ -243,6 +259,11 @@ impl FieldBuilder {
243259
self
244260
}
245261

262+
fn customize_fn(&mut self, customize_fn: Ident) -> &mut Self {
263+
self.customize_fn = Some(customize_fn);
264+
self
265+
}
266+
246267
fn build(self) -> Field {
247268
let ident = self.ident;
248269
let justify = self.justify;
@@ -251,6 +272,7 @@ impl FieldBuilder {
251272
let bold = self.bold;
252273
let order = self.order.unwrap_or(usize::MAX);
253274
let display_fn = self.display_fn;
275+
let customize_fn = self.customize_fn;
254276
let span = self.span;
255277

256278
let title = self
@@ -266,6 +288,7 @@ impl FieldBuilder {
266288
bold,
267289
order,
268290
display_fn,
291+
customize_fn,
269292
span,
270293
}
271294
}

cli-table-derive/src/lib.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
//!
1616
//! ## Simple usage
1717
//!
18-
//! ```rust,ignore
18+
//! ```rust
1919
//! use cli_table::{format::Justify, print_stdout, Cell, Style, Table};
2020
//!
2121
//! let table = vec![
@@ -104,6 +104,10 @@
104104
//! column with `order = 1` and so on.
105105
//! - `display_fn`: Used to print types which do not implement `Display` trait. Usage `#[table(display_fn = "<func_name>")]`.
106106
//! Signature of provided function should be `fn <func_name>(value: &<type>) -> impl Display`.
107+
//! - `customize_fn`: Used to customize style of a cell. Usage `#[table(customize_fn = "<func_name>")]`. Signature of
108+
//! provided function should be `fn <func_name>(cell: CellStruct, value: &<type>) -> CellStruct`. This attribute can
109+
//! be used when you want to change the formatting/style of a cell based on its contents. Note that this will
110+
//! overwrite all the style settings done by other attributes.
107111
//! - `skip`: Used to skip a field from table. Usage: `#[table(skip)]`
108112
//!
109113
//! For more information on configurations available on derive macro, go to `cli-table/examples/struct.rs`.
@@ -115,6 +119,33 @@
115119
//!
116120
//! For more information on handling CSV values, go to `cli-table/examples/csv.rs`.
117121
//!
122+
//! # Styling
123+
//!
124+
//! Style of a table/cell can be modified by calling functions of [`Style`] trait. It is implementated by both
125+
//! [`TableStruct`] and [`CellStruct`].
126+
//!
127+
//! For individually formatting each cell of a table, `justify`, `align` and `padding` functions can be used from
128+
//! `CellStruct`.
129+
//!
130+
//! In addition to this, borders and separators of a table can be customized by calling `border` and `separator`
131+
//! functions in `TableStruct`. For example, to create a borderless table:
132+
//!
133+
//! ```rust,ignore
134+
//! use cli_table::{Cell, Table, TableStruct, format::{Justify, Border}, print_stdout};
135+
//!
136+
//! fn get_table() -> TableStruct {
137+
//! vec![
138+
//! vec!["Tom".cell(), 10.cell().justify(Justify::Right)],
139+
//! vec!["Jerry".cell(), 15.cell().justify(Justify::Right)],
140+
//! vec!["Scooby Doo".cell(), 20.cell().justify(Justify::Right)],
141+
//! ]
142+
//! .table()
143+
//! }
144+
//!
145+
//! let table = get_table().border(Border::builder().build()); // Attaches an empty border to the table
146+
//! assert!(print_stdout(table).is_ok());
147+
//! ```
148+
//!
118149
//! # Features
119150
//!
120151
//! - `derive`: Enables derive macro for creating tables using structs. **Enabled** by default.

cli-table-derive/src/table.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub fn table(input: DeriveInput) -> Result<TokenStream> {
2929
let color = field.color;
3030
let bold = field.bold;
3131
let display_fn = field.display_fn;
32+
let customize_fn = field.customize_fn;
3233
let span = field.span;
3334

3435
let cell = match display_fn {
@@ -71,6 +72,12 @@ pub fn table(input: DeriveInput) -> Result<TokenStream> {
7172
};
7273
}
7374

75+
if let Some(customize_fn) = customize_fn {
76+
row = quote_spanned! {span=>
77+
#customize_fn (#row, &self. #ident)
78+
};
79+
}
80+
7481
field_rows.push(row);
7582
}
7683

cli-table/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ Below is the output of the table we created using derive macro:
107107
column with `order = 1` and so on.
108108
- `display_fn`: Used to print types which do not implement `Display` trait. Usage `#[table(display_fn = "<func_name>")]`.
109109
Signature of provided function should be `fn <func_name>(value: &<type>) -> impl Display`.
110+
- `customize_fn`: Used to customize style of a cell. Usage `#[table(customize_fn = "<func_name>")]`. Signature of
111+
provided function should be `fn <func_name>(cell: CellStruct, value: &<type>) -> CellStruct`. This attribute can
112+
be used when you want to change the formatting/style of a cell based on its contents. Note that this will
113+
overwrite all the style settings done by other attributes.
110114
- `skip`: Used to skip a field from table. Usage: `#[table(skip)]`
111115

112116
For more information on configurations available on derive macro, go to `cli-table/examples/struct.rs`.
@@ -118,6 +122,33 @@ use `TryFrom<&mut Reader> for TableStruct` trait implementation to convert `csv:
118122

119123
For more information on handling CSV values, go to `cli-table/examples/csv.rs`.
120124

125+
## Styling
126+
127+
Style of a table/cell can be modified by calling functions of [`Style`] trait. It is implementated by both
128+
[`TableStruct`] and [`CellStruct`].
129+
130+
For individually formatting each cell of a table, `justify`, `align` and `padding` functions can be used from
131+
`CellStruct`.
132+
133+
In addition to this, borders and separators of a table can be customized by calling `border` and `separator`
134+
functions in `TableStruct`. For example, to create a borderless table:
135+
136+
```rust
137+
use cli_table::{Cell, Table, TableStruct, format::{Justify, Border}, print_stdout};
138+
139+
fn get_table() -> TableStruct {
140+
vec![
141+
vec!["Tom".cell(), 10.cell().justify(Justify::Right)],
142+
vec!["Jerry".cell(), 15.cell().justify(Justify::Right)],
143+
vec!["Scooby Doo".cell(), 20.cell().justify(Justify::Right)],
144+
]
145+
.table()
146+
}
147+
148+
let table = get_table().border(Border::builder().build()); // Attaches an empty border to the table
149+
assert!(print_stdout(table).is_ok());
150+
```
151+
121152
## Features
122153

123154
- `derive`: Enables derive macro for creating tables using structs. **Enabled** by default.

cli-table/src/lib.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@
104104
//! column with `order = 1` and so on.
105105
//! - `display_fn`: Used to print types which do not implement `Display` trait. Usage `#[table(display_fn = "<func_name>")]`.
106106
//! Signature of provided function should be `fn <func_name>(value: &<type>) -> impl Display`.
107+
//! - `customize_fn`: Used to customize style of a cell. Usage `#[table(customize_fn = "<func_name>")]`. Signature of
108+
//! provided function should be `fn <func_name>(cell: CellStruct, value: &<type>) -> CellStruct`. This attribute can
109+
//! be used when you want to change the formatting/style of a cell based on its contents. Note that this will
110+
//! overwrite all the style settings done by other attributes.
107111
//! - `skip`: Used to skip a field from table. Usage: `#[table(skip)]`
108112
//!
109113
//! For more information on configurations available on derive macro, go to `cli-table/examples/struct.rs`.
@@ -115,6 +119,33 @@
115119
//!
116120
//! For more information on handling CSV values, go to `cli-table/examples/csv.rs`.
117121
//!
122+
//! # Styling
123+
//!
124+
//! Style of a table/cell can be modified by calling functions of [`Style`] trait. It is implementated by both
125+
//! [`TableStruct`] and [`CellStruct`].
126+
//!
127+
//! For individually formatting each cell of a table, `justify`, `align` and `padding` functions can be used from
128+
//! `CellStruct`.
129+
//!
130+
//! In addition to this, borders and separators of a table can be customized by calling `border` and `separator`
131+
//! functions in `TableStruct`. For example, to create a borderless table:
132+
//!
133+
//! ```rust
134+
//! use cli_table::{Cell, Table, TableStruct, format::{Justify, Border}, print_stdout};
135+
//!
136+
//! fn get_table() -> TableStruct {
137+
//! vec![
138+
//! vec!["Tom".cell(), 10.cell().justify(Justify::Right)],
139+
//! vec!["Jerry".cell(), 15.cell().justify(Justify::Right)],
140+
//! vec!["Scooby Doo".cell(), 20.cell().justify(Justify::Right)],
141+
//! ]
142+
//! .table()
143+
//! }
144+
//!
145+
//! let table = get_table().border(Border::builder().build()); // Attaches an empty border to the table
146+
//! assert!(print_stdout(table).is_ok());
147+
//! ```
148+
//!
118149
//! # Features
119150
//!
120151
//! - `derive`: Enables derive macro for creating tables using structs. **Enabled** by default.
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
error: `title` only accepts `&str` values
2-
--> $DIR/title-string-value.rs:5:21
1+
error: Invalid value for #[table(title = "field_name")]
2+
--> $DIR/title-string-value.rs:6:21
33
|
4-
5 | #[table(title = 1)]
4+
6 | #[table(title = 1)]
55
| ^

0 commit comments

Comments
 (0)