pub struct Table { /* private fields */ }
Expand description
A flexible table renderer with advanced styling and layout capabilities.
Table
provides a comprehensive solution for rendering tabular data in terminal
applications. It supports a wide range of customization options including borders,
styling functions, width/height constraints, text wrapping, and scrolling.
§Features
- Flexible Content: Supports headers, multiple data rows, and various data sources
- Advanced Styling: Cell-by-cell styling with function-based or closure-based approaches
- Border Control: Granular control over all border elements (top, bottom, sides, separators)
- Layout Management: Width/height constraints with automatic wrapping and truncation
- Scrolling Support: Offset-based scrolling for large datasets
- ANSI-Aware: Proper handling of ANSI escape sequences in cell content
- Memory Safe: Built-in protections against excessive memory usage
§Builder Pattern
Table
uses a fluent builder pattern where each method returns Self
, allowing
for method chaining. Call render()
to generate the final string representation.
§Examples
§Basic Table
use lipgloss_table::Table;
let mut table = Table::new()
.headers(vec!["Name", "Age", "City"])
.row(vec!["Alice", "30", "New York"])
.row(vec!["Bob", "25", "London"]);
println!("{}", table.render());
§Styled Table with Width Constraint
use lipgloss_table::{Table, zebra_style};
use lipgloss::rounded_border;
let mut table = Table::new()
.headers(vec!["Product", "Description", "Price"])
.rows(vec![
vec!["Widget A", "A useful widget for all your needs", "$19.99"],
vec!["Widget B", "An even more useful widget", "$29.99"],
])
.width(50)
.border(rounded_border())
.style_func(zebra_style);
println!("{}", table.render());
§Scrollable Table with Height Limit
use lipgloss_table::Table;
let mut large_table = Table::new()
.headers(vec!["ID", "Data"])
.height(10) // Limit to 10 lines total
.offset(20); // Start from row 20 (scrolling)
// Add many rows...
for i in 1..=1000 {
large_table = large_table.row(vec![i.to_string(), format!("Data {}", i)]);
}
println!("{}", large_table.render());
println!("Actual height: {}", large_table.compute_height());
Implementations§
Source§impl Table
impl Table
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new Table
with default settings and no content.
The default table configuration includes:
- Rounded borders (
lipgloss::rounded_border()
) - All border sides enabled (top, bottom, left, right, header separator, column separators)
- Row separators disabled
- Text wrapping enabled
- No width or height constraints
- No content (headers or data rows)
- Basic styling function (
default_styles
)
§Returns
A new Table
instance ready for configuration via the builder pattern.
§Examples
use lipgloss_table::Table;
let table = Table::new();
assert_eq!(table.compute_height(), 2); // Just top and bottom borders
use lipgloss_table::Table;
let mut table = Table::new()
.headers(vec!["Column 1", "Column 2"])
.row(vec!["Data 1", "Data 2"]);
println!("{}", table.render());
Sourcepub fn clear_rows(self) -> Self
pub fn clear_rows(self) -> Self
Removes all data rows from the table while preserving headers and settings.
This method clears only the table’s data content, leaving headers, styling, borders, and other configuration unchanged. It’s useful for reusing a configured table with different data.
§Returns
The Table
instance with all data rows removed, enabling method chaining.
§Examples
use lipgloss_table::Table;
let mut table = Table::new()
.headers(vec!["Name", "Age"])
.row(vec!["Alice", "30"])
.row(vec!["Bob", "25"])
.clear_rows()
.row(vec!["Charlie", "35"]);
// Table now has headers and only Charlie's row
println!("{}", table.render());
Sourcepub fn style_func(self, style: StyleFunc) -> Self
pub fn style_func(self, style: StyleFunc) -> Self
Sets a simple function-based styling function for table cells.
This method accepts a function pointer that determines the style for each
cell based on its row and column position. The function receives the row
index (with HEADER_ROW
for headers) and column index, returning a
Style
to apply to that cell.
Using this method will clear any previously set boxed style function.
§Arguments
style
- A function that takes(row: i32, col: usize) -> Style
§Returns
The Table
instance with the style function applied, enabling method chaining.
§Examples
use lipgloss_table::{Table, HEADER_ROW, header_row_style};
use lipgloss::{Style, Color};
// Using a predefined style function
let table1 = Table::new()
.headers(vec!["Name", "Age"])
.style_func(header_row_style);
// Using a custom style function
let custom_style = |row: i32, col: usize| {
match (row, col) {
(HEADER_ROW, _) => Style::new().bold(true),
(_, 0) => Style::new().foreground(Color::from("#00FF00")),
_ => Style::new(),
}
};
let table2 = Table::new()
.headers(vec!["Status", "Message"])
.style_func(custom_style);
Sourcepub fn style_func_boxed<F>(self, style: F) -> Self
pub fn style_func_boxed<F>(self, style: F) -> Self
Sets a flexible closure-based styling function that can capture variables from its environment.
This method allows for more complex styling logic than style_func
by accepting
a closure that can capture variables from the surrounding scope. This is useful
when your styling logic needs to reference external data, configuration, or state.
The closure is boxed and stored, allowing it to outlive the current scope while maintaining access to captured variables.
§Type Parameters
F
- A closure type that implementsFn(i32, usize) -> Style + Send + Sync + 'static
§Arguments
style
- A closure that takes(row: i32, col: usize) -> Style
§Returns
The Table
instance with the boxed style function applied, enabling method chaining.
§Examples
use lipgloss_table::{Table, HEADER_ROW};
use lipgloss::{Style, Color};
// Capture colors from the environment
let error_color = Color::from("#FF0000");
let success_color = Color::from("#00FF00");
let warning_color = Color::from("#FFAA00");
let mut table = Table::new()
.headers(vec!["Status", "Message", "Code"])
.row(vec!["Error", "Something failed", "500"])
.row(vec!["Success", "All good", "200"])
.row(vec!["Warning", "Be careful", "400"])
.style_func_boxed(move |row: i32, col: usize| {
match (row, col) {
(HEADER_ROW, _) => Style::new().bold(true),
(_, 0) => {
// Style status column based on content
match row {
0 => Style::new().foreground(error_color.clone()),
1 => Style::new().foreground(success_color.clone()),
2 => Style::new().foreground(warning_color.clone()),
_ => Style::new(),
}
}
_ => Style::new(),
}
});
println!("{}", table.render());
Sourcepub fn border_style(self, style: Style) -> Self
pub fn border_style(self, style: Style) -> Self
Sets the style for the table border.
Sourcepub fn border_top(self, v: bool) -> Self
pub fn border_top(self, v: bool) -> Self
Sets whether or not the top border is rendered.
Sourcepub fn border_bottom(self, v: bool) -> Self
pub fn border_bottom(self, v: bool) -> Self
Sets whether or not the bottom border is rendered.
Sourcepub fn border_left(self, v: bool) -> Self
pub fn border_left(self, v: bool) -> Self
Sets whether or not the left border is rendered.
Sourcepub fn border_right(self, v: bool) -> Self
pub fn border_right(self, v: bool) -> Self
Sets whether or not the right border is rendered.
Sourcepub fn border_header(self, v: bool) -> Self
pub fn border_header(self, v: bool) -> Self
Sets whether or not the header separator is rendered.
Sourcepub fn border_column(self, v: bool) -> Self
pub fn border_column(self, v: bool) -> Self
Sets whether or not column separators are rendered.
Sourcepub fn border_row(self, v: bool) -> Self
pub fn border_row(self, v: bool) -> Self
Sets whether or not row separators are rendered.
Sourcepub fn headers<I, S>(self, headers: I) -> Self
pub fn headers<I, S>(self, headers: I) -> Self
Sets the column headers for the table.
Headers are displayed at the top of the table and are typically styled differently from data rows (e.g., bold text). The number of headers determines the number of columns in the table.
§Type Parameters
I
- An iterator type that yields items convertible toString
S
- A type that can be converted intoString
§Arguments
headers
- An iterable collection of header values (strings, string slices, etc.)
§Returns
The Table
instance with headers set, enabling method chaining.
§Examples
use lipgloss_table::Table;
// Using string slices
let table1 = Table::new()
.headers(vec!["Name", "Age", "City"]);
// Using owned strings
let headers = vec!["ID".to_string(), "Description".to_string()];
let table2 = Table::new()
.headers(headers);
// Using an array
let table3 = Table::new()
.headers(["Product", "Price", "Stock"]);
Sourcepub fn render(&mut self) -> String
pub fn render(&mut self) -> String
Renders the table to a complete string representation.
This method performs the final rendering step, calculating layout dimensions, applying styles, and constructing the complete table string with borders, headers, and data rows. It must be called to generate the visual output.
The rendering process includes:
- Calculating optimal column widths and row heights
- Applying cell styles and text wrapping/truncation
- Constructing borders and separators
- Handling height constraints and overflow indicators
§Returns
A String
containing the complete rendered table with ANSI escape sequences
for styling and proper spacing.
§Examples
use lipgloss_table::{Table, header_row_style};
let mut table = Table::new()
.headers(vec!["Name", "Score"])
.row(vec!["Alice", "95"])
.row(vec!["Bob", "87"])
.style_func(header_row_style);
let output = table.render();
println!("{}", output);
use lipgloss_table::Table;
let mut table = Table::new()
.headers(vec!["Product", "Description"])
.row(vec!["Widget", "A very long description that will wrap"])
.width(30);
let output = table.render();
// Output will be wrapped to fit within 30 characters width
println!("{}", output);
Sourcepub fn compute_height(&self) -> usize
pub fn compute_height(&self) -> usize
Computes the total height the table will occupy when rendered.
This method calculates the exact number of terminal lines the table will use when rendered, including all borders, headers, data rows, and separators. It’s useful for layout planning, especially when working with height-constrained terminals or when implementing scrolling interfaces.
The calculation includes:
- Top and bottom borders (if enabled)
- Header row and header separator (if headers exist)
- All data rows with their calculated heights
- Row separators between data rows (if enabled)
§Returns
The total height in terminal lines as a usize
.
§Examples
use lipgloss_table::Table;
let table = Table::new();
assert_eq!(table.compute_height(), 2); // Just top and bottom borders
let table_with_content = Table::new()
.headers(vec!["Name", "Age"])
.row(vec!["Alice", "30"]);
// Height = top border + header + header separator + data row + bottom border
assert_eq!(table_with_content.compute_height(), 5);
use lipgloss_table::Table;
let mut large_table = Table::new()
.headers(vec!["ID", "Data"])
.height(10); // Height constraint
for i in 1..=100 {
large_table = large_table.row(vec![i.to_string(), format!("Data {}", i)]);
}
large_table.render(); // Must render first to populate heights
let height = large_table.compute_height();
// compute_height() returns the natural height, not constrained height
// The actual rendered output will be constrained to 10 lines
assert!(height > 10); // Natural height is larger than constraint
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Table
impl !RefUnwindSafe for Table
impl !Send for Table
impl !Sync for Table
impl Unpin for Table
impl !UnwindSafe for Table
Blanket Implementations§
Source§impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
Source§fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
Source§fn adapt_into(self) -> D
fn adapt_into(self) -> D
Source§impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
Source§fn arrays_from(colors: C) -> T
fn arrays_from(colors: C) -> T
Source§impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
Source§fn arrays_into(self) -> C
fn arrays_into(self) -> C
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
Source§type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
parameters
when converting.Source§fn cam16_into_unclamped(
self,
parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>,
) -> T
fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T
self
into C
, using the provided parameters.Source§impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
Source§fn components_from(colors: C) -> T
fn components_from(colors: C) -> T
Source§impl<T> FromAngle<T> for T
impl<T> FromAngle<T> for T
Source§fn from_angle(angle: T) -> T
fn from_angle(angle: T) -> T
angle
.Source§impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
Source§fn from_stimulus(other: U) -> T
fn from_stimulus(other: U) -> T
other
into Self
, while performing the appropriate scaling,
rounding and clamping.Source§impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
Source§fn into_angle(self) -> U
fn into_angle(self) -> U
T
.Source§impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
Source§type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
parameters
when converting.Source§fn into_cam16_unclamped(
self,
parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>,
) -> T
fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T
self
into C
, using the provided parameters.Source§impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
Source§fn into_color(self) -> U
fn into_color(self) -> U
Source§impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
Source§fn into_color_unclamped(self) -> U
fn into_color_unclamped(self) -> U
Source§impl<T> IntoStimulus<T> for T
impl<T> IntoStimulus<T> for T
Source§fn into_stimulus(self) -> T
fn into_stimulus(self) -> T
self
into T
, while performing the appropriate scaling,
rounding and clamping.Source§impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
Source§type Error = <C as TryFromComponents<T>>::Error
type Error = <C as TryFromComponents<T>>::Error
try_into_colors
fails to cast.Source§fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
Source§impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
Source§fn try_into_color(self) -> Result<U, OutOfBounds<U>>
fn try_into_color(self) -> Result<U, OutOfBounds<U>>
OutOfBounds
error is returned which contains
the unclamped color. Read more