tabled/
lib.rs

1//! An easy to use library for pretty print tables of Rust `struct`s and `enum`s.
2//!
3//! There's two approaches to construct a table.
4//!
5//! 1. When the type of data is known.
6//! 2. When it's unknown.
7//!
8//! Here you can work with both.\
9//! For first approach you shall find [`derive::Tabled`] macros being very helpfull.\
10//! For a later one you shall take a look at [`Builder`].
11//!
12//! There are a number of [`settings`] you can use\
13//! to change table appearance, layout and data itself.
14//!
15//! Beside a default [`Table`] type there are more,\
16//! more specific table which works best when there are some constraints.
17//!
18#![cfg_attr(
19    all(feature = "derive", feature = "std", feature = "assert"),
20    doc = "```"
21)]
22#![cfg_attr(
23    not(all(feature = "derive", feature = "std", feature = "assert")),
24    doc = "```ignore"
25)]
26//! use tabled::{
27//!     Tabled, Table, assert::assert_table,
28//!     settings::{Style, Alignment, object::Columns},
29//! };
30//!
31//! #[derive(Tabled)]
32//! struct Language {
33//!     name: &'static str,
34//!     designed_by: &'static str,
35//!     invented_year: usize,
36//! }
37//!
38//! let languages = vec![
39//!     Language{ name: "C", designed_by: "Dennis Ritchie", invented_year: 1972 },
40//!     Language{ name: "Rust", designed_by: "Graydon Hoare", invented_year: 2010 },
41//!     Language{ name: "Go", designed_by: "Rob Pike", invented_year: 2009 },
42//! ];
43//!
44//! let mut table = Table::new(languages);
45//! table.with(Style::modern());
46//! table.modify(Columns::first(), Alignment::right());
47//!
48//! assert_table!(
49//!     table,
50//!     "┌──────┬────────────────┬───────────────┐"
51//!     "│ name │ designed_by    │ invented_year │"
52//!     "├──────┼────────────────┼───────────────┤"
53//!     "│    C │ Dennis Ritchie │ 1972          │"
54//!     "├──────┼────────────────┼───────────────┤"
55//!     "│ Rust │ Graydon Hoare  │ 2010          │"
56//!     "├──────┼────────────────┼───────────────┤"
57//!     "│   Go │ Rob Pike       │ 2009          │"
58//!     "└──────┴────────────────┴───────────────┘"
59//! );
60//! ```
61//!
62//! ## Building table step by step
63//!
64//! When you data scheme is not known at compile time.\
65//! You most likely will not able to relay on [`Table`].\
66//! One option would be is to use [`Builder`].
67//!
68#![cfg_attr(all(feature = "std", feature = "assert"), doc = "```")]
69#![cfg_attr(not(all(feature = "std", feature = "assert")), doc = "```ignore")]
70//! use std::iter::once;
71//! use tabled::{builder::Builder, settings::Style, assert::assert_table};
72//!
73//! const X: usize = 3;
74//! const Y: usize = 5;
75//!
76//! let mut builder = Builder::default();
77//!
78//! for i in 0..X {
79//!     let row = (0..Y).map(|j| (i * j).to_string());
80//!     builder.push_record(row);
81//! }
82//!
83//! builder.insert_record(0, (0..Y).map(|i| i.to_string()));
84//! builder.insert_column(0, once(String::new()).chain((0..X).map(|i| i.to_string())));
85//!
86//! let mut table = builder.build();
87//! table.with(Style::rounded());
88//!
89//! assert_table!(
90//!     table,
91//!     "╭───┬───┬───┬───┬───┬───╮"
92//!     "│   │ 0 │ 1 │ 2 │ 3 │ 4 │"
93//!     "├───┼───┼───┼───┼───┼───┤"
94//!     "│ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │"
95//!     "│ 1 │ 0 │ 1 │ 2 │ 3 │ 4 │"
96//!     "│ 2 │ 0 │ 2 │ 4 │ 6 │ 8 │"
97//!     "╰───┴───┴───┴───┴───┴───╯"
98//! );
99//! ```
100//!
101//! ## Settings
102//!
103//! You can find lots of settings in [`tabled::settings`].
104//!
105//! ## Hints
106//!
107//! [`Table`] can be build from vast majority of Rust's standard types.\
108//! This allows you to run the following code.
109//!
110#![cfg_attr(all(feature = "std", feature = "assert"), doc = "```")]
111#![cfg_attr(not(all(feature = "std", feature = "assert")), doc = "```ignore")]
112//! use tabled::{Table, assert::assert_table};
113//!
114//! let table = Table::new(&[1, 2, 3]);
115//!
116//! assert_table!(
117//!     table,
118//!     "+-----+"
119//!     "| i32 |"
120//!     "+-----+"
121//!     "| 1   |"
122//!     "+-----+"
123//!     "| 2   |"
124//!     "+-----+"
125//!     "| 3   |"
126//!     "+-----+"
127//! );
128//! ```
129//!
130//! You can compine types, and settings together using a tupples.\
131//! And achive magical results.
132//!
133#![cfg_attr(all(feature = "std", feature = "assert"), doc = "```")]
134#![cfg_attr(not(all(feature = "std", feature = "assert")), doc = "```ignore")]
135//! use tabled::{
136//!     Table, assert::assert_table,
137//!     settings::{style::{Style, HorizontalLine}, Alignment, Padding},
138//! };
139//!
140//! let data = &[(1, 2, "Hello"), (1, 3, "World")];
141//!
142//! let mut table = Table::new(data);
143//! table.with(
144//!     Style::modern()
145//!         .remove_horizontal()
146//!         .horizontals([(1, HorizontalLine::inherit(Style::modern()))])
147//! );
148//! table.with((Alignment::right(), Padding::new(2, 0, 2, 1)));
149//!
150//! assert_table!(
151//!     table,
152//!     "┌─────┬─────┬───────┐"
153//!     "│     │     │       │"
154//!     "│     │     │       │"
155//!     "│  i32│  i32│   &str│"
156//!     "│     │     │       │"
157//!     "├─────┼─────┼───────┤"
158//!     "│     │     │       │"
159//!     "│     │     │       │"
160//!     "│    1│    2│  Hello│"
161//!     "│     │     │       │"
162//!     "│     │     │       │"
163//!     "│     │     │       │"
164//!     "│    1│    3│  World│"
165//!     "│     │     │       │"
166//!     "└─────┴─────┴───────┘"
167//! );
168//! ```
169//!
170//! Be ware you don't obligated to `collect` your data before building.
171//!
172#![cfg_attr(
173    all(feature = "derive", feature = "std", feature = "assert"),
174    doc = "```"
175)]
176#![cfg_attr(
177    not(all(feature = "derive", feature = "std", feature = "assert")),
178    doc = "```ignore"
179)]
180//! use tabled::{Tabled, Table, assert::assert_table};
181//!
182//! let data = (0..3).map(|i| [i, i * 2, i * 3]);
183//!
184//! let mut table = Table::new(data);
185//!
186//! assert_table!(
187//!     table,
188//!     "+---+---+---+"
189//!     "| 0 | 1 | 2 |"
190//!     "+---+---+---+"
191//!     "| 0 | 0 | 0 |"
192//!     "+---+---+---+"
193//!     "| 1 | 2 | 3 |"
194//!     "+---+---+---+"
195//!     "| 2 | 4 | 6 |"
196//!     "+---+---+---+"
197//! );
198//! ```
199//!
200//! Build table using [`row!`] and [`col!`] macros.
201//!
202#![cfg_attr(
203    all(feature = "macros", feature = "std", feature = "assert"),
204    doc = "```"
205)]
206#![cfg_attr(
207    not(all(feature = "macros", feature = "std", feature = "assert")),
208    doc = "```ignore"
209)]
210//! use tabled::{row, col, assert::assert_table};
211//!
212//! let table = row![
213//!     col!["Hello", "World", "!"],
214//!     col!["Hello"; 3],
215//!     col!["World"; 3],
216//! ];
217//!
218//! assert_table!(
219//!     table,
220//!     "+-----------+-----------+-----------+"
221//!     "| +-------+ | +-------+ | +-------+ |"
222//!     "| | Hello | | | Hello | | | World | |"
223//!     "| +-------+ | +-------+ | +-------+ |"
224//!     "| | World | | | Hello | | | World | |"
225//!     "| +-------+ | +-------+ | +-------+ |"
226//!     "| | !     | | | Hello | | | World | |"
227//!     "| +-------+ | +-------+ | +-------+ |"
228//!     "+-----------+-----------+-----------+"
229//! );
230//! ```
231//!
232//! # `no_std`
233//!
234//! Only [`CompactTable`] can be used in `no_std` context.
235//!
236//! # Features
237//!
238//! - `std`     - Used by default. If not its considered `no_std` with a limited set of functionality.
239//! - `derive`  - Used by default. A support for `Tabled` derive macro.
240//! - `ansi`    - A support for ANSI sequences.
241//! - `macros`  - A support for `row!`, `col!` macro.
242//!
243//! ## More information
244//!
245//! You can find more examples of settings and attributes in
246//! [README.md](https://github.com/zhiburt/tabled/blob/master/README.md)
247//!
248//! [`Builder`]: crate::builder::Builder
249//! [`IterTable`]: crate::tables::IterTable
250//! [`CompactTable`]: crate::tables::CompactTable
251//! [`fmt::Write`]: core::fmt::Write
252//! [`row!`]: crate::row
253//! [`col!`]: crate::col
254//! [`tabled::settings`]: crate::settings
255
256#![cfg_attr(not(any(feature = "std", test)), no_std)]
257#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
258#![doc(
259    html_logo_url = "https://raw.githubusercontent.com/zhiburt/tabled/86ac146e532ce9f7626608d7fd05072123603a2e/assets/tabled-gear.svg"
260)]
261#![deny(unused_must_use)]
262#![warn(
263    missing_docs,
264    rust_2018_idioms,
265    rust_2018_compatibility,
266    missing_debug_implementations,
267    unreachable_pub,
268    future_incompatible,
269    single_use_lifetimes,
270    trivial_casts,
271    trivial_numeric_casts,
272    unused_extern_crates,
273    unused_import_braces,
274    unused_qualifications,
275    unused_results,
276    unused_variables,
277    variant_size_differences
278)]
279#![allow(clippy::uninlined_format_args)]
280
281#[cfg(feature = "macros")]
282mod macros;
283#[cfg(feature = "std")]
284mod tabled;
285mod util;
286
287#[cfg(feature = "assert")]
288#[cfg_attr(docsrs, doc(cfg(feature = "assert")))]
289pub mod assert;
290#[cfg(feature = "std")]
291#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
292pub mod builder;
293#[cfg(feature = "derive")]
294#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
295pub mod derive;
296pub mod grid;
297pub mod iter;
298pub mod settings;
299pub mod tables;
300
301#[cfg(feature = "std")]
302#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
303pub use crate::{tabled::Tabled, tables::Table};
304
305#[cfg(feature = "derive")]
306#[cfg_attr(docsrs, doc(cfg(feature = "derive")))]
307pub use derive::Tabled;