cli-boxes 0.1.1

Unicode box drawing characters for creating beautiful CLI interfaces
Documentation
# CLI Boxes

A Rust library providing Unicode box-drawing characters for creating beautiful CLI interfaces.

## Features

- **9 Different Box Styles**: From simple single-line to decorative arrows (including invisible)
- **Unicode Support**: Proper Unicode box-drawing characters
- **ASCII Fallback**: Classic ASCII style for maximum compatibility
- **Ergonomic API**: Both low-level `BoxChars` and high-level `BorderStyle` enum
- **Builder Pattern**: Fluent API for creating custom box characters
- **Constructor Methods**: Direct instantiation with `new()` method
- **String Conversion**: Parse styles from strings and convert to strings
- **Serde Support**: Serialize and deserialize box character sets (feature-gated)
- **Type Safety**: Strong typing ensures correct usage
- **Iterator Support**: Enumerate all available styles
- **Performance Optimized**: Zero-allocation string parsing and const evaluation

## Box Styles

| Style           | Example      | Description                        |
| --------------- | ------------ | ---------------------------------- |
| `NONE`          | `        `   | Invisible borders (all spaces)     |
| `SINGLE`        | `┌─┐│┘─└│`   | Clean single-line borders          |
| `DOUBLE`        | `╔═╗║╝═╚║`   | Bold double-line borders           |
| `ROUND`         | `╭─╮│╯─╰│`   | Soft rounded corners               |
| `BOLD`          | `┏━┓┃┛━┗┃`   | Thick, bold lines                  |
| `SINGLE_DOUBLE` | `╓─╖║╜─╙║`   | Single horizontal, double vertical |
| `DOUBLE_SINGLE` | `╒═╕│╛═╘│`   | Double horizontal, single vertical |
| `CLASSIC`       | `+─+\|+─+\|` | ASCII-compatible characters        |
| `ARROW`         | `↘↓↙←↖↑↗→`   | Decorative arrow style             |

## Quick Start

Add this to your `Cargo.toml`:

```toml
[dependencies]
cli-boxes = "0.1.0"

# Enable serde support (optional)
cli-boxes = { version = "0.1.0", features = ["serde"] }
```

## Usage

### Using BorderStyle Enum (Recommended)

```rust
use cli_boxes::{BorderStyle, BoxChars};

// Use the ergonomic BorderStyle enum
let style = BorderStyle::Single;
let box_chars = style.chars();

// Or convert directly
let box_chars = BoxChars::from(BorderStyle::Double);

// Parse from string (case-insensitive, supports kebab-case)
let style: BorderStyle = "single-double".parse().unwrap();
let box_chars = style.chars();

// Convert to string
println!("Current style: {}", BorderStyle::Round); // Output: "round"
```

### Using BoxChars Directly

```rust
use cli_boxes::BoxChars;

// Create a simple box with single-line characters
let box_chars = BoxChars::SINGLE;
println!("{}{}{}",
    box_chars.top_left,
    box_chars.top.to_string().repeat(10),
    box_chars.top_right
);
println!("{}          {}", box_chars.left, box_chars.right);
println!("{}{}{}",
    box_chars.bottom_left,
    box_chars.bottom.to_string().repeat(10),
    box_chars.bottom_right
);
```

Output:

```
┌──────────┐
│          │
└──────────┘
```

### Iterating Through All Styles

```rust
use cli_boxes::BorderStyle;

// Iterate through all available styles
for style in BorderStyle::all() {
    let chars = style.chars();
    println!("{}: {}{}{}", style, chars.top_left, chars.top, chars.top_right);
}
```

## String Parsing

The `BorderStyle` enum supports parsing from strings with flexible formatting:

```rust
use std::str::FromStr;
use cli_boxes::BorderStyle;

// Case-insensitive parsing
let style1 = "SINGLE".parse::<BorderStyle>().unwrap();
let style2 = "double".parse::<BorderStyle>().unwrap();

// Supports both snake_case and kebab-case
let style3 = "single_double".parse::<BorderStyle>().unwrap();
let style4 = "single-double".parse::<BorderStyle>().unwrap();

// Error handling with helpful suggestions
match "invalid_style".parse::<BorderStyle>() {
    Ok(style) => println!("Parsed: {}", style),
    Err(e) => println!("Error: {}", e),
    // Error: Invalid border style: 'invalid_style'. Did you mean one of: none, single, double, round, bold, single_double, double_single, classic, arrow?
}
```

## Custom Box Characters

You can create custom box character sets in several ways:

### Using the Constructor

```rust
use cli_boxes::BoxChars;

let custom = BoxChars::new('*', '-', '*', '|', '*', '-', '*', '|');
```

### Using the Builder Pattern (Recommended)

```rust
use cli_boxes::BoxChars;

// Set all corners and sides uniformly
let uniform = BoxChars::builder()
    .corners('*')
    .horizontal('-')
    .vertical('|')
    .build();

// Mix and match for asymmetric designs
let asymmetric = BoxChars::builder()
    .top_left('╭')
    .top_right('╮')
    .bottom_left('╰')
    .bottom_right('╯')
    .horizontal('─')
    .vertical('│')
    .build();

// Override specific characters
let mixed = BoxChars::builder()
    .corners('●')
    .horizontal('═')
    .vertical('║')
    .top_left('╔') // Override just the top-left corner
    .build();
```

### Using Struct Literals

```rust
use cli_boxes::BoxChars;

let custom = BoxChars {
    top_left: '*',
    top: '-',
    top_right: '*',
    right: '|',
    bottom_right: '*',
    bottom: '-',
    bottom_left: '*',
    left: '|',
};
```

## API Reference

### BorderStyle Methods

- `chars()` - Get the `BoxChars` for this style
- `all()` - Iterator over all available styles
- `to_string()` - Convert to lowercase string representation
- `parse()` - Parse from string (via `FromStr`)

### BoxChars Methods

- `new()` - Constructor for creating custom box characters
- `builder()` - Returns a `BoxCharsBuilder` for fluent API construction
- `default()` - Returns `BoxChars::SINGLE`

### BoxChars Constants

- `BoxChars::NONE` - Invisible borders (spaces)
- `BoxChars::SINGLE` - Single-line Unicode borders
- `BoxChars::DOUBLE` - Double-line Unicode borders
- `BoxChars::ROUND` - Rounded corner borders
- `BoxChars::BOLD` - Bold/thick line borders
- `BoxChars::SINGLE_DOUBLE` - Mixed single/double borders
- `BoxChars::DOUBLE_SINGLE` - Mixed double/single borders
- `BoxChars::CLASSIC` - ASCII-compatible borders
- `BoxChars::ARROW` - Decorative arrow borders

### BoxCharsBuilder Methods

- `corners(char)` - Set all four corner characters
- `horizontal(char)` - Set top and bottom border characters
- `vertical(char)` - Set left and right border characters
- `top_left(char)`, `top(char)`, `top_right(char)` - Set individual characters
- `right(char)`, `bottom_right(char)`, `bottom(char)` - Set individual characters
- `bottom_left(char)`, `left(char)` - Set individual characters
- `build()` - Construct the final `BoxChars`

## Requirements

- Rust 2024 edition or later
- No additional runtime dependencies (except optional `serde` and `strum`)

## Performance

This library is designed for performance:

- **Zero Allocations**: String parsing avoids heap allocations through optimized byte-level comparison
- **Const Evaluation**: All predefined box characters are compile-time constants
- **Efficient Parsing**: Case-insensitive parsing with hyphen/underscore normalization without string conversion

## Serde Support

When the `serde` feature is enabled, all types can be serialized and deserialized:

```toml
[dependencies]
cli-boxes = { version = "0.1.0", features = ["serde"] }
serde_json = "1.0" # For JSON serialization (not included with cli-boxes)
```

```rust
use cli_boxes::{BoxChars, BorderStyle};
use serde_json;

// Serialize a BorderStyle
let style = BorderStyle::Double;
let json = serde_json::to_string(&style).unwrap();

// Serialize BoxChars
let chars = BoxChars::ROUND;
let json = serde_json::to_string(&chars).unwrap();
```

## License

This project is licensed under the MIT OR Apache-2.0 License - see the [LICENSE](LICENSE) file for details.