Skip to content

Commit 9bb0ae8

Browse files
Merge pull request #27 from tertsdiepraam/api-changes
API changes
2 parents 154253a + 3faf4d6 commit 9bb0ae8

File tree

6 files changed

+389
-517
lines changed

6 files changed

+389
-517
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ rust-version = "1.70"
1515
name = "term_grid"
1616

1717
[dependencies]
18-
unicode-width = "0.1.11"
18+
textwrap = { version = "0.16.0", default-features = false, features = ["unicode-width"] }

README.md

Lines changed: 68 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,24 @@
22
[![dependency status](https://deps.rs/repo/github/uutils/uutils-term-grid/status.svg)](https://deps.rs/repo/github/uutils/uutils-term-grid)
33
[![CodeCov](https://codecov.io/gh/uutils/uutils-term-grid/branch/master/graph/badge.svg)](https://codecov.io/gh/uutils/uutils-term-grid)
44

5-
65
# uutils-term-grid
76

8-
This library arranges textual data in a grid format suitable for fixed-width fonts, using an algorithm to minimise the amount of space needed.
7+
This library arranges textual data in a grid format suitable for fixed-width
8+
fonts, using an algorithm to minimise the amount of space needed.
99

1010
---
1111

12-
This library is forked from the [`rust-term-grid`](https://github.com/ogham/rust-term-grid) library.
12+
This library is forked from the unmaintained
13+
[`rust-term-grid`](https://github.com/ogham/rust-term-grid) library. The core
14+
functionality has remained the same, with some additional bugfixes, performance
15+
improvements and a new API.
1316

1417
---
1518

1619
# Installation
1720

18-
This crate works with `cargo`. Add the following to your `Cargo.toml` dependencies section:
21+
This crate works with `cargo`. Add the following to your `Cargo.toml`
22+
dependencies section:
1923

2024
```toml
2125
[dependencies]
@@ -24,70 +28,81 @@ uutils_term_grid = "0.3"
2428

2529
The Minimum Supported Rust Version is 1.70.
2630

31+
## Creating a grid
2732

28-
## Usage
33+
To add data to a grid, first create a new [`Grid`] value with a list of strings
34+
and a set of options.
2935

30-
This library arranges textual data in a grid format suitable for fixed-width fonts, using an algorithm to minimise the amount of space needed.
31-
For example:
36+
There are three options that must be specified in the [`GridOptions`] value that
37+
dictate how the grid is formatted:
3238

33-
```rust
34-
use term_grid::{Grid, GridOptions, Direction, Filling, Cell};
39+
- [`filling`][filling]: what to put in between two columns — either a number of
40+
spaces, or a text string;
41+
- [`direction`][direction]: specifies whether the cells should go along rows, or
42+
columns:
43+
- [`Direction::LeftToRight`][LeftToRight] starts them in the top left and
44+
moves _rightwards_, going to the start of a new row after reaching the final
45+
column;
46+
- [`Direction::TopToBottom`][TopToBottom] starts them in the top left and
47+
moves _downwards_, going to the top of a new column after reaching the final
48+
row.
49+
- [`width`][width]: the width to fill the grid into. Usually, this should be the
50+
width of the terminal.
3551

36-
let mut grid = Grid::new(GridOptions {
37-
filling: Filling::Spaces(1),
38-
direction: Direction::LeftToRight,
39-
});
52+
In practice, creating a grid can be done as follows:
4053

41-
for s in &["one", "two", "three", "four", "five", "six", "seven",
42-
"eight", "nine", "ten", "eleven", "twelve"]
43-
{
44-
grid.add(Cell::from(*s));
45-
}
46-
47-
println!("{}", grid.fit_into_width(24).unwrap());
54+
```rust
55+
use term_grid::{Grid, GridOptions, Direction, Filling};
56+
57+
// Create a `Vec` of text to put in the grid
58+
let cells = vec![
59+
"one", "two", "three", "four", "five", "six",
60+
"seven", "eight", "nine", "ten", "eleven", "twelve"
61+
];
62+
63+
// Then create a `Grid` with those cells.
64+
// The grid requires several options:
65+
// - The filling determines the string used as separator
66+
// between the columns.
67+
// - The direction specifies whether the layout should
68+
// be done row-wise or column-wise.
69+
// - The width is the maximum width that the grid might
70+
// have.
71+
let grid = Grid::new(
72+
cells,
73+
GridOptions {
74+
filling: Filling::Spaces(1),
75+
direction: Direction::LeftToRight,
76+
width: 24,
77+
}
78+
);
79+
80+
// A `Grid` implements `Display` and can be printed directly.
81+
println!("{grid}");
4882
```
4983

5084
Produces the following tabular result:
5185

52-
```
86+
```text
5387
one two three four
5488
five six seven eight
5589
nine ten eleven twelve
5690
```
5791

92+
[filling]: struct.GridOptions.html#structfield.filling
93+
[direction]: struct.GridOptions.html#structfield.direction
94+
[width]: struct.GridOptions.html#structfield.width
95+
[LeftToRight]: enum.Direction.html#variant.LeftToRight
96+
[TopToBottom]: enum.Direction.html#variant.TopToBottom
5897

59-
## Creating a grid
60-
61-
To add data to a grid, first create a new `Grid` value, and then add cells to them with the `add` method.
62-
63-
There are two options that must be specified in the `GridOptions` value that dictate how the grid is formatted:
64-
65-
- `filling`: what to put in between two columns - either a number of spaces, or a text string;
66-
- `direction`, which specifies whether the cells should go along rows, or columns:
67-
- `Direction::LeftToRight` starts them in the top left and moves *rightwards*, going to the start of a new row after reaching the final column;
68-
- `Direction::TopToBottom` starts them in the top left and moves *downwards*, going to the top of a new column after reaching the final row.
69-
70-
71-
## Displaying a grid
72-
73-
When display a grid, you can either specify the number of columns in advance, or try to find the maximum number of columns that can fit in an area of a given width.
74-
75-
Splitting a series of cells into columns - or, in other words, starting a new row every *n* cells - is achieved with the `fit_into_columns` method on a `Grid` value.
76-
It takes as its argument the number of columns.
77-
78-
Trying to fit as much data onto one screen as possible is the main use case for specifying a maximum width instead.
79-
This is achieved with the `fit_into_width` method.
80-
It takes the maximum allowed width, including separators, as its argument.
81-
However, it returns an *optional* `Display` value, depending on whether any of the cells actually had a width greater than the maximum width!
82-
If this is the case, your best bet is to just output the cells with one per line.
83-
84-
85-
## Cells and data
98+
## Width of grid cells
8699

87-
Grids do not take `String`s or `&str`s - they take `Cells`.
100+
This library calculates the width of strings as displayed in the terminal using
101+
the [`textwrap`][textwrap] library (with the [`display_width`][display_width] function).
102+
This takes into account the width of characters and ignores ANSI codes.
88103

89-
A **Cell** is a struct containing an individual cell’s contents, as a string, and its pre-computed length, which gets used when calculating a grid’s final dimensions.
90-
Usually, you want the *Unicode width* of the string to be used for this, so you can turn a `String` into a `Cell` with the `.into()` method.
104+
The width calculation is currently not configurable. If you have a use-case for
105+
which this calculation is wrong, please open an issue.
91106

92-
However, you may also want to supply your own width: when you already know the width in advance, or when you want to change the measurement, such as skipping over terminal control characters.
93-
For cases like these, the fields on the `Cell` values are public, meaning you can construct your own instances as necessary.
107+
[textwrap]: https://docs.rs/textwrap/latest/textwrap/index.html
108+
[display_width]: https://docs.rs/textwrap/latest/textwrap/core/fn.display_width.html

examples/basic.rs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
extern crate term_grid;
2-
use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
1+
// For the full copyright and license information, please view the LICENSE
2+
// file that was distributed with this source code.
3+
4+
use term_grid::{Direction, Filling, Grid, GridOptions};
35

46
// This produces:
57
//
@@ -12,19 +14,16 @@ use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
1214
// 64 | 8192 | 1048576 | 134217728 | 17179869184 | 2199023255552 |
1315

1416
fn main() {
15-
let mut grid = Grid::new(GridOptions {
16-
direction: Direction::TopToBottom,
17-
filling: Filling::Text(" | ".into()),
18-
});
17+
let cells: Vec<_> = (0..48).map(|i| 2_isize.pow(i).to_string()).collect();
1918

20-
for i in 0..48 {
21-
let cell = Cell::from(2_isize.pow(i).to_string());
22-
grid.add(cell)
23-
}
19+
let grid = Grid::new(
20+
cells,
21+
GridOptions {
22+
direction: Direction::TopToBottom,
23+
filling: Filling::Text(" | ".into()),
24+
width: 80,
25+
},
26+
);
2427

25-
if let Some(grid_display) = grid.fit_into_width(80) {
26-
println!("{}", grid_display);
27-
} else {
28-
println!("Couldn't fit grid into 80 columns!");
29-
}
28+
println!("{}", grid);
3029
}

examples/big.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
// For the full copyright and license information, please view the LICENSE
22
// file that was distributed with this source code.
33

4-
extern crate term_grid;
5-
use term_grid::{Cell, Direction, Filling, Grid, GridOptions};
4+
use term_grid::{Direction, Filling, Grid, GridOptions};
65

76
fn main() {
8-
let mut grid = Grid::new(GridOptions {
9-
direction: Direction::TopToBottom,
10-
filling: Filling::Text(" | ".into()),
11-
});
12-
137
let mut n: u64 = 1234;
148
for _ in 0..50 {
9+
let mut cells = Vec::new();
1510
for _ in 0..10000 {
16-
grid.add(Cell::from(n.to_string()));
11+
cells.push(n.to_string());
1712
n = n.overflowing_pow(2).0 % 100000000;
1813
}
1914

20-
if let Some(grid_display) = grid.fit_into_width(80) {
21-
println!("{}", grid_display);
22-
} else {
23-
println!("Couldn't fit grid into 80 columns!");
24-
}
15+
let grid = Grid::new(
16+
cells,
17+
GridOptions {
18+
direction: Direction::TopToBottom,
19+
filling: Filling::Text(" | ".into()),
20+
width: 80,
21+
},
22+
);
23+
24+
println!("{grid}");
2525
}
2626
}

0 commit comments

Comments
 (0)