tree_fmt/
lib.rs

1//! Tree and Table Formatter Module
2//!
3//! Provides abstract, reusable formatters for hierarchical data display.
4//!
5//! # Features
6//!
7//! - **Generic `TreeNode`**: Works with any data type
8//! - **`TreeBuilder`**: Constructs trees from flat data with path-based insertion
9//! - **`TreeFormatter`**: Renders trees with configurable symbols and display options
10//! - **`TableFormatter`**: Renders tabular data with borders and alignment
11//! - **String Output**: All formatters return `String`, no direct console output
12
13#![ allow( clippy::missing_inline_in_public_items ) ]
14#![ allow( clippy::must_use_candidate ) ]
15#![ allow( clippy::std_instead_of_core ) ]
16#![ allow( clippy::format_push_string ) ]
17//!
18//! The library supports three interchangeable display formats:
19//!
20//! - **Table**: Horizontal tabular display (standard row-column layout)
21//! - **Expanded**: Vertical record display (`PostgreSQL` `\x` mode, key-value pairs)
22//! - **Tree**: Hierarchical tree display (outline with box-drawing characters)
23//!
24//! # Examples
25//!
26//! ## Same data in all three formats
27//!
28//! ```
29//! use tree_fmt::{ RowBuilder, TableFormatter, ExpandedFormatter, TreeFormatter };
30//!
31//! // Create tabular data
32//! let tree = RowBuilder::new( vec![ "Name".into(), "Age".into() ] )
33//!   .add_row( vec![ "Alice".into(), "30".into() ] )
34//!   .add_row( vec![ "Bob".into(), "25".into() ] )
35//!   .build();
36//!
37//! // Table format
38//! let table_fmt = TableFormatter::new();
39//! let output = table_fmt.format( &tree );
40//!
41//! // Expanded format
42//! let expanded_fmt = ExpandedFormatter::new();
43//! let output = expanded_fmt.format( &tree );
44//!
45//! // Tree format (table-shaped tree)
46//! let tree_fmt = TreeFormatter::default();
47//! let output = tree_fmt.format( &tree, Clone::clone );
48//! ```
49//!
50//! ## Expanded format with colored keys
51//!
52//! ```
53//! use tree_fmt::{ RowBuilder, ExpandedFormatter, ExpandedConfig };
54//!
55//! let tree = RowBuilder::new( vec![ "Name".into(), "Score".into() ] )
56//!   .add_row( vec![ "Alice".into(), "95".into() ] )
57//!   .build();
58//!
59//! // Gray keys for terminal output (PostgreSQL style)
60//! let formatter = ExpandedFormatter::with_config(
61//!   ExpandedConfig::new().colorize_keys( true )
62//! );
63//! let output = formatter.format( &tree );
64//! ```
65//!
66//! ## Property list style (colon separator)
67//!
68//! ```
69//! use tree_fmt::{ RowBuilder, ExpandedFormatter, ExpandedConfig };
70//!
71//! let tree = RowBuilder::new( vec![ "Command".into(), "Status".into() ] )
72//!   .add_row( vec![ "build".into(), "success".into() ] )
73//!   .build();
74//!
75//! // Property list style: no record headers, colon separator
76//! let formatter = ExpandedFormatter::with_config( ExpandedConfig::property_style() );
77//! let output = formatter.format( &tree );
78//! // Output:
79//! // Command: build
80//! // Status:  success
81//! ```
82//!
83//! ## Building and formatting a tree
84//!
85//! ```
86//! use tree_fmt::{ TreeBuilder, TreeFormatter };
87//!
88//! let tree = TreeBuilder::new( "root" )
89//!   .insert( &[ "src", "main.rs" ], 150 )
90//!   .insert( &[ "src", "lib.rs" ], 300 )
91//!   .build();
92//!
93//! let formatter = TreeFormatter::new();
94//! let output = formatter.format( &tree, | lines | format!( "{} lines", lines ) );
95//! println!( "{}", output );
96//! ```
97//!
98//! ## Building from items
99//!
100//! ```
101//! use tree_fmt::TreeBuilder;
102//! use std::path::PathBuf;
103//!
104//! let files = vec![
105//!   ( PathBuf::from( "src/main.rs" ), 100 ),
106//!   ( PathBuf::from( "tests/test.rs" ), 50 ),
107//! ];
108//!
109//! let tree = TreeBuilder::from_items( &files, | ( path, _size ) | {
110//!   path.components().map( | c | c.as_os_str().to_string_lossy().to_string() ).collect()
111//! }, | ( path, size ) | ( path.clone(), *size ) );
112//! ```
113//!
114//! ## Formatting a table
115//!
116//! ```
117//! use tree_fmt::{ RowBuilder, TableFormatter };
118//!
119//! let tree = RowBuilder::new( vec![ "File".into(), "Lines".into() ] )
120//!   .add_row( vec![ "main.rs".into(), "100".into() ] )
121//!   .add_row( vec![ "lib.rs".into(), "200".into() ] )
122//!   .build();
123//!
124//! let formatter = TableFormatter::new();
125//! let output = formatter.format( &tree );
126//! println!( "{}", output );
127//! ```
128
129// Module declarations
130mod data;
131mod config;
132mod helpers;
133mod builder;
134mod table_tree;
135pub mod conversions;
136pub mod formatters;
137
138#[ cfg( feature = "themes" ) ]
139pub mod themes;
140
141// Public re-exports - Core data types (always available)
142pub use data::{
143  TreeNode, ColumnData,
144  TableView, TableMetadata, DataType, TableShapedView
145};
146pub use config::{
147  TreeConfig, TableConfig, ExpandedConfig, PaddingSide, TreeSymbols,
148  BorderVariant, HeaderSeparatorVariant, ColumnSeparator,
149};
150pub use helpers::{ visual_len, pad_to_width, truncate_cell };
151pub use builder::TreeBuilder;
152pub use table_tree::RowBuilder;
153
154// Format trait (always available)
155pub use formatters::{ Format, FormatError };
156
157// Conditional formatter exports (feature-gated)
158#[ cfg( any(
159  feature = "table_plain",
160  feature = "table_minimal",
161  feature = "table_bordered",
162  feature = "table_markdown",
163  feature = "table_grid",
164  feature = "table_unicode",
165  feature = "table_csv",
166  feature = "table_tsv",
167  feature = "table_compact"
168) ) ]
169pub use formatters::TableFormatter;
170
171#[ cfg( any(
172  feature = "expanded_postgres",
173  feature = "expanded_property"
174) ) ]
175pub use formatters::ExpandedFormatter;
176
177#[ cfg( any(
178  feature = "tree_hierarchical",
179  feature = "tree_aligned",
180  feature = "tree_aggregated"
181) ) ]
182pub use formatters::TreeFormatter;
183
184#[ cfg( feature = "format_logfmt" ) ]
185pub use formatters::LogfmtFormatter;
186
187#[ cfg( any(
188  feature = "html_minimal",
189  feature = "html_bootstrap",
190  feature = "html_tailwind",
191  feature = "html_custom"
192) ) ]
193pub use formatters::{ HtmlFormatter, HtmlVariant };
194
195#[ cfg( any(
196  feature = "sql_ansi",
197  feature = "sql_postgres",
198  feature = "sql_mysql",
199  feature = "sql_sqlite"
200) ) ]
201pub use formatters::{ SqlFormatter, SqlVariant };
202
203#[ cfg( feature = "format_json" ) ]
204pub use formatters::JsonFormatter;
205
206#[ cfg( feature = "format_yaml" ) ]
207pub use formatters::YamlFormatter;
208
209#[ cfg( feature = "format_toml" ) ]
210pub use formatters::TomlFormatter;
211
212#[ cfg( feature = "format_text" ) ]
213pub use formatters::{ TextFormatter, TextVariant };
214
215// Color themes (feature-gated)
216#[ cfg( feature = "themes" ) ]
217pub use themes::{ ColorTheme, ColorThemeBuilder };
218
219// Backward compatibility trait (always available for now)
220pub use formatters::TableShapedFormatter;