Skip to main content

BoxyBuilder

Struct BoxyBuilder 

Source
pub struct BoxyBuilder<'a> { /* private fields */ }
Expand description

The BoxyBuilder struct implements a fluent builder pattern for creating Boxy instances.

This builder provides a more expressive and readable way to create and configure text boxes. Each method returns the builder instance itself, allowing method calls to be chained together. When the configuration is complete, call the build() method to create the actual Boxy instance.

§Examples

use boxy_cli::prelude::*;

// Create and display a text box in a single fluent sequence
Boxy::builder()
    .box_type(BoxType::Double)
    .color("#00ffff")
    .padding(BoxPad::uniform(1), BoxPad::from_tldr(2, 2, 1, 1))
    .align(BoxAlign::Center)
    .add_segment("Hello, Boxy!", "#ffffff", BoxAlign::Center)
    .add_line("This is a new line.", "#32CD32")
    .add_segment("Another section", "#663399", BoxAlign::Left)
    .width(50)
    .build()
    .display();

Implementations§

Source§

impl<'a> BoxyBuilder<'a>

Source

pub fn new() -> Self

Creates a new BoxyBuilder with default values.

This creates a builder with the following default values:

  • Box type: BoxType::Single
  • Color: empty string (will use white if not set)
  • Padding: zero on all sides
  • Alignment: BoxAlign::Left
  • No text segments
§Examples
use boxy_cli::prelude::*;

let builder = BoxyBuilder::new();
// Configure the builder with various methods
let my_box = builder.box_type(BoxType::Double)
                   .color("#00ffff")
                   .build();

Typically used through the Boxy::builder() factory method:

use boxy_cli::prelude::*;

let builder = Boxy::builder(); // Same as BoxyBuilder::new()
Source

pub fn box_type(self, box_type: BoxType) -> Self

Sets the border type for the text box.

This determines the visual style of the box borders, including the characters used for corners, edges, and intersections. Different styles can create different visual effects, from simple ASCII-style boxes to double-lined or rounded boxes.

§Arguments
  • box_type - The border style from the BoxType enum
§Returns

The builder instance for method chaining

§Examples
use boxy_cli::prelude::*;

let builder = Boxy::builder()
    .box_type(BoxType::Double); // Use double-lined borders

// Or try other border styles
let rounded_box = Boxy::builder()
    .box_type(BoxType::Rounded)
    .build();
Source

pub fn color(self, box_color: &str) -> Self

Sets the border color for the text box.

This method defines the color of the box borders, including corners, edges, and intersections. The color is specified using a hexadecimal color code (e.g. “#00ffff” for cyan).

§Arguments
  • box_color - Hex color code (e.g. \"#ffffff\"). Falls back to white with a stderr warning on invalid input
§Returns

The builder instance for method chaining

§Examples
use boxy_cli::prelude::*;

// Create a box with cyan borders
let cyan_box = Boxy::builder()
    .color("#00ffff")
    .build();

// Create a box with red borders
let red_box = Boxy::builder()
    .color("#ff0000")
    .build();
§Note

The actual appearance depends on terminal support for colors.

Source

pub fn add_segment(self, text: &str, color: &str, text_align: BoxAlign) -> Self

Adds a new text segment to the box with specified text, color, and alignment.

Each segment represents a distinct section of the text box that will be separated by horizontal dividers. This method is used to add the first or subsequent major segments of content.

§Arguments
  • text - The text content for this segment
  • color - Hex color code (e.g. \"#ffffff\") for the text. Falls back to white with a stderr warning on invalid input
  • text_align - The alignment for this text segment (left, center, right)
§Returns

The builder instance for method chaining

§Examples
use boxy_cli::prelude::*;

let my_box = Boxy::builder()
    // Add a centered header segment in white
    .add_segment("Header", "#ffffff", BoxAlign::Center)
    // Add a left-aligned content segment in green
    .add_segment("Content goes here", "#00ff00", BoxAlign::Left)
    .build();
Source

pub fn add_col_segment(self, text_align: BoxAlign, column_count: usize) -> Self

Adds a new columnar segment to the box. Adds a new columnar segment to the box with column_count side-by-side columns.

Columns start empty and are populated with add_col_line or add_col_line_indx. All columns default to equal width; use segment_ratios to customize.

§Arguments
  • text_align - Alignment applied to text within each column
  • column_count - Number of columns (must be at least 1)
§Returns

The builder instance for method chaining

§Panics

Panics if column_count is 0.

§Examples
use boxy_cli::prelude::*;

let my_box = Boxy::builder()
    .add_col_segment(BoxAlign::Left, 2)
    .add_col_line("Left column", "#ffffff", 0)
    .add_col_line("Right column", "#ffffff", 1)
    .build();
Source

pub fn add_line(self, text: &str, color: &str) -> Self

Adds a new line of text to the most recently added segment.

This method adds a line of text to the last segment that was created. The new line will appear below the existing content in that segment. Unlike add_segment(), this does not create a new segment with a divider.

§Arguments
  • text - The text content to add as a new line
  • color - Hex color code (e.g. \"#ffffff\") for the text. Falls back to white with a stderr warning on invalid input
§Returns

The builder instance for method chaining

§Examples
use boxy_cli::prelude::*;

let my_box = Boxy::builder()
    // Add a header segment
    .add_segment("Header", "#ffffff", BoxAlign::Center)
    // Add a subheader as a new line in the same segment
    .add_line("Subheader text", "#aaaaaa")
    // Add a different segment with a divider
    .add_segment("Content section", "#00ff00", BoxAlign::Left)
    .build();
Source

pub fn add_col_line(self, text: &str, color: &str, col_index: usize) -> Self

Adds a line of text to a specific column of the most recently added columnar segment.

Convenience method — no need to specify the segment index. Mirrors add_col_line_indx for when you’re building top-to-bottom.

§Arguments
  • text - The text content to add
  • color - Hex color code (e.g. \"#ffffff\") for the text. Falls back to white with a stderr warning on invalid input
  • col_index - Zero-based index of the column to add this line into
§Returns

The builder instance for method chaining

§Panics

Panics if no segment exists, if the last segment is not columnar, or if col_index is out of bounds.

§Examples
use boxy_cli::prelude::*;

let my_box = Boxy::builder()
    .add_col_segment(BoxAlign::Left, 3)
    .add_col_line("Name",     "#aaaaaa", 0)
    .add_col_line("Status",   "#aaaaaa", 1)
    .add_col_line("Notes",    "#aaaaaa", 2)
    .add_col_line("Lumio V2", "#ffffff", 0)
    .add_col_line("Shipped",  "#32CD32", 1)
    .add_col_line("Done",     "#ffffff", 2)
    .build();
Source

pub fn add_col_line_indx( self, text: &str, color: &str, seg_index: usize, col_index: usize, ) -> Self

Adds a line of text to a specific column of a specific columnar segment by index.

Use this when you need to populate segments out of order or return to an earlier segment. For sequential top-to-bottom building, prefer add_col_line.

§Arguments
  • text - The text content to add
  • color - Hex color code (e.g. \"#ffffff\") for the text. Falls back to white with a stderr warning on invalid input
  • seg_index - Zero-based index of the columnar segment
  • col_index - Zero-based index of the column within that segment
§Returns

The builder instance for method chaining

§Panics

Panics if seg_index is out of bounds, if that segment is not columnar, or if col_index is out of bounds for that segment’s column count.

§Examples
use boxy_cli::prelude::*;

let my_box = Boxy::builder()
    .add_segment("Header", "#ffffff", BoxAlign::Center)
    .add_col_segment(BoxAlign::Left, 2)
    .add_col_line_indx("Left",  "#ffffff", 1, 0)
    .add_col_line_indx("Right", "#ffffff", 1, 1)
    .build();
Source

pub fn align(self, alignment: BoxAlign) -> Self

Sets the overall alignment of the text box within the terminal.

This method controls the horizontal positioning of the entire text box relative to the terminal width. It does not affect the alignment of text within the box segments, which is specified individually when adding segments.

§Behaviour with external padding

When set to BoxAlign::Center, external left/right padding affects the width of the box (more padding → narrower box) but not its position. The box always occupies the center of the terminal regardless of padding values, as long as the terminal is wide enough. See padding and external_padding.

§Arguments
  • alignment - The alignment to use: BoxAlign::Left, BoxAlign::Center, or BoxAlign::Right
§Returns

The builder instance for method chaining

§Examples
use boxy_cli::prelude::*;

// center the box — external padding will shrink it but keep it centerd
let centered_box = Boxy::builder()
    .align(BoxAlign::Center)
    .add_segment("centerd in the terminal", "#ffffff", BoxAlign::Left)
    .build();

// Right-align the box
let right_box = Boxy::builder()
    .align(BoxAlign::Right)
    .add_segment("Aligned to the right", "#ffffff", BoxAlign::Left)
    .build();
Source

pub fn internal_padding(self, padding: BoxPad) -> Self

Sets the internal padding between the box border and its text content.

Internal padding creates space between the border of the box and the text inside it, providing visual breathing room for the content.

§Arguments
  • padding - A BoxPad instance specifying the internal padding values
§Returns

The builder instance for method chaining

§Examples
use boxy_cli::prelude::*;

// Set uniform internal padding of 2 spaces on all sides
let padded_box = Boxy::builder()
    .internal_padding(BoxPad::uniform(2))
    .build();

// Set different padding for each side (top, left, bottom, right)
let custom_pad_box = Boxy::builder()
    .internal_padding(BoxPad::from_tldr(1, 3, 1, 3))
    .build();
Source

pub fn external_padding(self, padding: BoxPad) -> Self

Sets the external padding between the terminal edges and the text box.

External padding creates space between the edges of the terminal and the border of the box. This affects the positioning of the box within the terminal.

§Arguments
  • padding - A BoxPad instance specifying the external padding values
§Returns

The builder instance for method chaining

§Examples
use boxy_cli::prelude::*;

// Add 5 spaces of external padding on all sides
let padded_box = Boxy::builder()
    .external_padding(BoxPad::uniform(5))
    .build();

// Add 10 spaces of padding on the left side only
let left_padded_box = Boxy::builder()
    .external_padding(BoxPad::from_tldr(0, 10, 0, 0))
    .build();
Source

pub fn padding(self, external: BoxPad, internal: BoxPad) -> Self

Sets both internal and external padding for the text box in a single call.

This is a convenience method that combines setting both external padding (between terminal edges and box) and internal padding (between box border and text) in one call.

§Arguments
  • external - A BoxPad instance for the external padding (between terminal edges and box)
  • internal - A BoxPad instance for the internal padding (between box border and text)
§Returns

The builder instance for method chaining

§Examples
use boxy_cli::prelude::*;

// Set both padding types at once
let box_with_padding = Boxy::builder()
    .padding(
        BoxPad::from_tldr(1, 5, 1, 5),  // external padding
        BoxPad::uniform(2)              // internal padding
    )
    .build();
Source

pub fn width(self, width: usize) -> Self

Sets a fixed width for the box instead of dynamically sizing to the terminal width.

By default, the text box automatically adjusts its width based on the terminal size. This method allows you to specify a fixed width instead, which can be useful for creating boxes of consistent size or for controlling the layout of multiple boxes.

The width value includes the two border characters, so the usable inner text area is width - 2 columns (minus any internal padding). Pass 0 to return to dynamic terminal-width sizing.

§Arguments
  • width - Total box width in terminal columns, including border characters
§Returns

The builder instance for method chaining

§Examples
use boxy_cli::prelude::*;

Boxy::builder()
    .width(60) // 60 total: 2 borders + 58 usable
    .add_segment("Fixed width box", "#ffffff", BoxAlign::Center)
    .build()
    .display();

Setting to 0 restores dynamic sizing:

use boxy_cli::prelude::*;

Boxy::builder()
    .width(0) // dynamic — sizes to terminal
    .add_segment("Dynamic width", "#ffffff", BoxAlign::Left)
    .build();
Source

pub fn height(self, height: usize) -> Self

Sets a fixed height for the text box by adding whitespace above and below the text.

§Note

This feature is experimental and may not work as expected in the current version. Setting height to 0 returns to dynamic sizing based on content.

This method allows you to specify a fixed height for the box, which can be useful for creating boxes of consistent size or for controlling the layout of multiple boxes.

§Arguments
  • height - The desired height in number of lines (including borders)
§Returns

The builder instance for method chaining

§Examples
use boxy_cli::prelude::*;

// Create a box with a fixed height of 20 lines
let fixed_height_box = Boxy::builder()
    .height(20)
    .add_segment("This box has a fixed height", "#ffffff", BoxAlign::Center)
    .build();
Source

pub fn segment_ratios(self, seg_index: usize, ratios: Vec<usize>) -> Self

Sets the column width ratios for a columnar segment.

Ratios are relative — vec![1, 2, 1] gives the middle column twice the width of the others. The number of ratios must exactly match the column count the segment was created with. If never called, columns default to equal widths.

§Arguments
  • seg_index - Zero-based index of the columnar segment to configure
  • ratios - One ratio value per column; values are relative, not absolute widths
§Returns

The builder instance for method chaining

§Panics

Panics if seg_index refers to a Single text segment rather than a columnar one, or if ratios.len() does not match that segment’s column count.

§Examples
use boxy_cli::prelude::*;

Boxy::builder()
    .add_col_segment(BoxAlign::Left, 3)
    .add_col_line("Name", "#aaaaaa", 0)
    .add_col_line("Status", "#aaaaaa", 1)
    .add_col_line("Notes", "#aaaaaa", 2)
    .segment_ratios(0, vec![1, 1, 2]) // Notes column gets twice the space
    .build()
    .display();
Source

pub fn set_terminal_width_offset(self, offset: i32) -> Self

Adjusts the effective terminal width used for dynamic box sizing.

§Note

This feature is experimental and may not work as expected in the current version. Setting height to 0 returns to dynamic sizing based on content.

When fixed_width is not set, the box width defaults to terminal_width - 20. This method lets you change that offset. A larger positive value makes the box narrower; a negative value makes it wider than the default. The default offset of -20 exists to leave a small margin; set to 0 to fill the full terminal width.

Has no effect when a fixed width is set via width.

§Arguments
  • offset - Characters to subtract from the terminal width (negative = wider)
§Returns

The builder instance for method chaining

§Examples
use boxy_cli::prelude::*;

// Fill the full terminal width
Boxy::builder()
    .set_terminal_width_offset(0)
    .add_segment("Full width box", "#ffffff", BoxAlign::Left)
    .build();
§Warning

Negative offsets large enough to exceed the terminal width will cause display issues. Prefer width for precise control.

Source

pub fn build(self) -> Boxy<'a>

Consumes the builder and returns a configured Boxy instance ready to display. (use .display() to output the box to stdout)

§Examples
use boxy_cli::prelude::*;

let mut b = Boxy::builder()
    .box_type(BoxType::Double)
    .color("#00ffff")
    .add_segment("Hello, boxy-cli!", "#ffffff", BoxAlign::Center)
    .build();

b.display();

Or chain directly into display:

use boxy_cli::prelude::*;

Boxy::builder()
    .add_segment("Hello, boxy-cli!", "#ffffff", BoxAlign::Center)
    .build()
    .display();

Trait Implementations§

Source§

impl<'a> Debug for BoxyBuilder<'a>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for BoxyBuilder<'a>

§

impl<'a> RefUnwindSafe for BoxyBuilder<'a>

§

impl<'a> Send for BoxyBuilder<'a>

§

impl<'a> Sync for BoxyBuilder<'a>

§

impl<'a> Unpin for BoxyBuilder<'a>

§

impl<'a> UnsafeUnpin for BoxyBuilder<'a>

§

impl<'a> UnwindSafe for BoxyBuilder<'a>

Blanket Implementations§

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> 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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> 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.