fast_rich/
box_drawing.rs

1//! Box drawing characters and styles.
2//!
3//! This module defines the `Box` struct which holds the character set for drawing
4//! boxes (panels, tables, etc.) and provides standard styles matching Python's `rich.box`.
5
6/// A structure defining the characters used to draw a box.
7///
8/// A box is composed of a top, middle (for rows/sections), and bottom part.
9/// Each part has a left, middle, right, and cross/divider character.
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub struct Box {
12    /// Top line
13    pub top: Line,
14    /// Header separator line
15    pub head: Line,
16    /// Middle line (row separator)
17    pub mid: Line,
18    /// Bottom line
19    pub bottom: Line,
20    /// Header row vertical lines
21    pub header: Line,
22    /// Content row vertical lines
23    pub cell: Line,
24}
25
26/// A structure defining the characters for a single horizontal line in a box.
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub struct Line {
29    pub left: char,
30    pub mid: char,
31    pub right: char,
32    pub cross: char,
33}
34
35impl Line {
36    pub const fn new(left: char, mid: char, right: char, cross: char) -> Self {
37        Self {
38            left,
39            mid,
40            right,
41            cross,
42        }
43    }
44}
45
46/// Standard ASCII box style.
47pub const ASCII: Box = Box {
48    top: Line::new('+', '-', '+', '+'),
49    head: Line::new('+', '-', '+', '+'),
50    mid: Line::new('+', '-', '+', '+'),
51    bottom: Line::new('+', '-', '+', '+'),
52    header: Line::new('|', ' ', '|', '|'),
53    cell: Line::new('|', ' ', '|', '|'),
54};
55
56/// ASCII box style with double-line header separator.
57pub const ASCII_DOUBLE_HEAD: Box = Box {
58    top: Line::new('+', '-', '+', '+'),
59    head: Line::new('+', '=', '+', '+'),
60    mid: Line::new('+', '-', '+', '+'),
61    bottom: Line::new('+', '-', '+', '+'),
62    header: Line::new('|', ' ', '|', '|'),
63    cell: Line::new('|', ' ', '|', '|'),
64};
65
66/// Simple square box using standard drawing characters.
67pub const SQUARE: Box = Box {
68    top: Line::new('┌', '─', '┐', '┬'),
69    head: Line::new('├', '─', '┤', '┼'),
70    mid: Line::new('├', '─', '┤', '┼'),
71    bottom: Line::new('└', '─', '┘', '┴'),
72    header: Line::new('│', ' ', '│', '│'),
73    cell: Line::new('│', ' ', '│', '│'),
74};
75
76/// Square box with double-line header separator.
77pub const SQUARE_DOUBLE_HEAD: Box = Box {
78    top: Line::new('┌', '─', '┐', '┬'),
79    head: Line::new('╞', '═', '╡', '╪'),
80    mid: Line::new('├', '─', '┤', '┼'),
81    bottom: Line::new('└', '─', '┘', '┴'),
82    header: Line::new('│', ' ', '│', '│'),
83    cell: Line::new('│', ' ', '│', '│'),
84};
85
86/// Minimal box (open sides).
87pub const MINIMAL: Box = Box {
88    top: Line::new(' ', '─', ' ', '─'),
89    head: Line::new(' ', '─', ' ', '─'),
90    mid: Line::new(' ', '─', ' ', '─'),
91    bottom: Line::new(' ', '─', ' ', '─'),
92    header: Line::new(' ', ' ', ' ', ' '),
93    cell: Line::new(' ', ' ', ' ', ' '),
94};
95
96/// Minimal box with heavy header separator.
97pub const MINIMAL_HEAVY_HEAD: Box = Box {
98    top: Line::new(' ', '─', ' ', '─'),
99    head: Line::new(' ', '━', ' ', '━'),
100    mid: Line::new(' ', '─', ' ', '─'),
101    bottom: Line::new(' ', '─', ' ', '─'),
102    header: Line::new(' ', ' ', ' ', ' '),
103    cell: Line::new(' ', ' ', ' ', ' '),
104};
105
106/// Minimal box with double-line header separator.
107pub const MINIMAL_DOUBLE_HEAD: Box = Box {
108    top: Line::new(' ', '─', ' ', '─'),
109    head: Line::new(' ', '═', ' ', '═'),
110    mid: Line::new(' ', '─', ' ', '─'),
111    bottom: Line::new(' ', '─', ' ', '─'),
112    header: Line::new(' ', ' ', ' ', ' '),
113    cell: Line::new(' ', ' ', ' ', ' '),
114};
115
116/// Box with only horizontal lines.
117pub const HORIZONTALS: Box = Box {
118    top: Line::new(' ', '─', ' ', '─'),
119    head: Line::new(' ', '─', ' ', '─'),
120    mid: Line::new(' ', '─', ' ', '─'),
121    bottom: Line::new(' ', '─', ' ', '─'),
122    header: Line::new(' ', ' ', ' ', ' '),
123    cell: Line::new(' ', ' ', ' ', ' '),
124};
125
126/// Rounded corners (very popular).
127pub const ROUNDED: Box = Box {
128    top: Line::new('╭', '─', '╮', '┬'),
129    head: Line::new('├', '─', '┤', '┼'),
130    mid: Line::new('├', '─', '┤', '┼'),
131    bottom: Line::new('╰', '─', '╯', '┴'),
132    header: Line::new('│', ' ', '│', '│'),
133    cell: Line::new('│', ' ', '│', '│'),
134};
135
136/// Heavy (bold) lines.
137pub const HEAVY: Box = Box {
138    top: Line::new('┏', '━', '┓', '┳'),
139    head: Line::new('┣', '━', '┫', '╋'),
140    mid: Line::new('┣', '━', '┫', '╋'),
141    bottom: Line::new('┗', '━', '┛', '┻'),
142    header: Line::new('┃', ' ', '┃', '┃'),
143    cell: Line::new('┃', ' ', '┃', '┃'),
144};
145
146/// Heavy edges but light inner lines.
147pub const HEAVY_EDGE: Box = Box {
148    top: Line::new('┏', '━', '┓', '┳'),
149    head: Line::new('┣', '━', '┫', '╇'),
150    mid: Line::new('┣', '━', '┫', '╇'),
151    bottom: Line::new('┗', '━', '┛', '┻'),
152    header: Line::new('┃', ' ', '┃', '┃'),
153    cell: Line::new('┃', ' ', '┃', '┃'),
154};
155
156/// Heavy header separator.
157pub const HEAVY_HEAD: Box = Box {
158    top: Line::new('┏', '━', '┓', '┳'),
159    head: Line::new('┡', '━', '┩', '╇'),
160    mid: Line::new('│', '─', '│', '┼'),
161    bottom: Line::new('└', '─', '┘', '┴'),
162    header: Line::new('┃', ' ', '┃', '┃'),
163    cell: Line::new('│', ' ', '│', '│'),
164};
165
166/// Double lines.
167pub const DOUBLE: Box = Box {
168    top: Line::new('╔', '═', '╗', '╦'),
169    head: Line::new('╠', '═', '╣', '╬'),
170    mid: Line::new('╠', '═', '╣', '╬'),
171    bottom: Line::new('╚', '═', '╝', '╩'),
172    header: Line::new('║', ' ', '║', '║'),
173    cell: Line::new('║', ' ', '║', '║'),
174};
175
176/// Double edges but single inner lines.
177pub const DOUBLE_EDGE: Box = Box {
178    top: Line::new('╔', '═', '╗', '╤'),
179    head: Line::new('╠', '═', '╣', '╪'),
180    mid: Line::new('╟', '─', '╢', '┼'),
181    bottom: Line::new('╚', '═', '╝', '╧'),
182    header: Line::new('║', ' ', '║', '║'),
183    cell: Line::new('║', ' ', '║', '║'),
184};