Struct Table

Source
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

Source

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());
Source

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());
Source

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);
Source

pub fn style_func_boxed<F>(self, style: F) -> Self
where F: Fn(i32, usize) -> Style + Send + Sync + 'static,

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 implements Fn(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());
Source

pub fn border(self, border: Border) -> Self

Sets the table border.

Source

pub fn border_style(self, style: Style) -> Self

Sets the style for the table border.

Source

pub fn border_top(self, v: bool) -> Self

Sets whether or not the top border is rendered.

Source

pub fn border_bottom(self, v: bool) -> Self

Sets whether or not the bottom border is rendered.

Source

pub fn border_left(self, v: bool) -> Self

Sets whether or not the left border is rendered.

Source

pub fn border_right(self, v: bool) -> Self

Sets whether or not the right border is rendered.

Source

pub fn border_header(self, v: bool) -> Self

Sets whether or not the header separator is rendered.

Source

pub fn border_column(self, v: bool) -> Self

Sets whether or not column separators are rendered.

Source

pub fn border_row(self, v: bool) -> Self

Sets whether or not row separators are rendered.

Source

pub fn headers<I, S>(self, headers: I) -> Self
where I: IntoIterator<Item = S>, S: Into<String>,

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 to String
  • S - A type that can be converted into String
§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"]);
Source

pub fn row<I, S>(self, row: I) -> Self
where I: IntoIterator<Item = S>, S: Into<String>,

Adds a single row to the table.

Source

pub fn rows<I, J, S>(self, rows: I) -> Self
where I: IntoIterator<Item = J>, J: IntoIterator<Item = S>, S: Into<String>,

Adds multiple rows to the table.

Source

pub fn data<D: Data + 'static>(self, data: D) -> Self

Sets the data source for the table.

Source

pub fn width(self, w: i32) -> Self

Sets a fixed width for the table.

Source

pub fn height(self, h: i32) -> Self

Sets a fixed height for the table.

Source

pub fn offset(self, o: usize) -> Self

Sets the row offset for the table (for scrolling).

Source

pub fn wrap(self, w: bool) -> Self

Sets whether text wrapping is enabled.

Source

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);
Source

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§

Source§

impl Default for Table

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Display for Table

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

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 S
where 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) -> D
where M: TransformMatrix<T>,

Convert the source color to the destination color using the specified method.
Source§

fn adapt_into(self) -> D

Convert the source color to the destination color using the bradford method by default.
Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T, C> ArraysFrom<C> for T
where C: IntoArrays<T>,

Source§

fn arrays_from(colors: C) -> T

Cast a collection of colors into a collection of arrays.
Source§

impl<T, C> ArraysInto<C> for T
where C: FromArrays<T>,

Source§

fn arrays_into(self) -> C

Cast this collection of arrays into a collection of colors.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for U
where T: FromCam16Unclamped<WpParam, U>,

Source§

type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar

The number type that’s used in parameters when converting.
Source§

fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T

Converts self into C, using the provided parameters.
Source§

impl<T, C> ComponentsFrom<C> for T
where C: IntoComponents<T>,

Source§

fn components_from(colors: C) -> T

Cast a collection of colors into a collection of color components.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromAngle<T> for T

Source§

fn from_angle(angle: T) -> T

Performs a conversion from angle.
Source§

impl<T, U> FromStimulus<U> for T
where U: IntoStimulus<T>,

Source§

fn from_stimulus(other: U) -> T

Converts other into Self, while performing the appropriate scaling, rounding and clamping.
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> IntoAngle<U> for T
where U: FromAngle<T>,

Source§

fn into_angle(self) -> U

Performs a conversion into T.
Source§

impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for U
where T: Cam16FromUnclamped<WpParam, U>,

Source§

type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar

The number type that’s used in parameters when converting.
Source§

fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T

Converts self into C, using the provided parameters.
Source§

impl<T, U> IntoColor<U> for T
where U: FromColor<T>,

Source§

fn into_color(self) -> U

Convert into T with values clamped to the color defined bounds Read more
Source§

impl<T, U> IntoColorUnclamped<U> for T
where U: FromColorUnclamped<T>,

Source§

fn into_color_unclamped(self) -> U

Convert into T. The resulting color might be invalid in its color space Read more
Source§

impl<T> IntoStimulus<T> for T

Source§

fn into_stimulus(self) -> T

Converts self into T, while performing the appropriate scaling, rounding and clamping.
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, C> TryComponentsInto<C> for T
where C: TryFromComponents<T>,

Source§

type Error = <C as TryFromComponents<T>>::Error

The error for when try_into_colors fails to cast.
Source§

fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>

Try to cast this collection of color components into a collection of colors. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T, U> TryIntoColor<U> for T
where U: TryFromColor<T>,

Source§

fn try_into_color(self) -> Result<U, OutOfBounds<U>>

Convert into T, returning ok if the color is inside of its defined range, otherwise an OutOfBounds error is returned which contains the unclamped color. Read more
Source§

impl<C, U> UintsFrom<C> for U
where C: IntoUints<U>,

Source§

fn uints_from(colors: C) -> U

Cast a collection of colors into a collection of unsigned integers.
Source§

impl<C, U> UintsInto<C> for U
where C: FromUints<U>,

Source§

fn uints_into(self) -> C

Cast this collection of unsigned integers into a collection of colors.