# 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
| `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;
### 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.