Skip to main content

unicode_plot/
border.rs

1/// The eight characters that make up a plot border (corners, sides, top/bottom).
2#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3pub struct BorderChars {
4    /// Top-left corner.
5    pub tl: char,
6    /// Top edge (repeated for the border width).
7    pub t: char,
8    /// Top-right corner.
9    pub tr: char,
10    /// Left edge.
11    pub l: char,
12    /// Right edge.
13    pub r: char,
14    /// Bottom-left corner.
15    pub bl: char,
16    /// Bottom edge (repeated for the border width).
17    pub b: char,
18    /// Bottom-right corner.
19    pub br: char,
20}
21
22/// Border style for a plot frame.
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
24#[non_exhaustive]
25pub enum BorderType {
26    /// Full box-drawing border: `┌─┐││└─┘`.
27    Solid,
28    /// Corner-only border with spaces for sides and edges.
29    Corners,
30    /// Barplot border with a tick mark (`┤`) on the left side.
31    Barplot,
32    #[doc(hidden)]
33    Ascii,
34}
35
36impl BorderType {
37    /// Returns the eight border characters for this border style.
38    #[must_use]
39    pub const fn chars(self) -> BorderChars {
40        match self {
41            Self::Solid => BorderChars {
42                tl: '┌',
43                t: '─',
44                tr: '┐',
45                l: '│',
46                r: '│',
47                bl: '└',
48                b: '─',
49                br: '┘',
50            },
51            Self::Corners => BorderChars {
52                tl: '┌',
53                t: ' ',
54                tr: '┐',
55                l: ' ',
56                r: ' ',
57                bl: '└',
58                b: ' ',
59                br: '┘',
60            },
61            Self::Barplot => BorderChars {
62                tl: '┌',
63                t: ' ',
64                tr: '┐',
65                l: '┤',
66                r: ' ',
67                bl: '└',
68                b: ' ',
69                br: '┘',
70            },
71            Self::Ascii => BorderChars {
72                tl: '+',
73                t: '-',
74                tr: '+',
75                l: '|',
76                r: '|',
77                bl: '+',
78                b: '-',
79                br: '+',
80            },
81        }
82    }
83}
84
85/// Returns the public border types in alphabetical order: Barplot, Corners, Solid.
86#[must_use]
87pub const fn border_types() -> &'static [BorderType] {
88    &[BorderType::Barplot, BorderType::Corners, BorderType::Solid]
89}
90
91#[cfg(test)]
92mod tests {
93    use super::{BorderType, border_types};
94
95    #[test]
96    fn solid_border_chars_match_reference() {
97        let chars = BorderType::Solid.chars();
98        assert_eq!(chars.tl, '┌');
99        assert_eq!(chars.t, '─');
100        assert_eq!(chars.tr, '┐');
101        assert_eq!(chars.l, '│');
102        assert_eq!(chars.r, '│');
103        assert_eq!(chars.bl, '└');
104        assert_eq!(chars.b, '─');
105        assert_eq!(chars.br, '┘');
106    }
107
108    #[test]
109    fn corners_border_chars_match_reference() {
110        let chars = BorderType::Corners.chars();
111        assert_eq!(chars.tl, '┌');
112        assert_eq!(chars.t, ' ');
113        assert_eq!(chars.tr, '┐');
114        assert_eq!(chars.l, ' ');
115        assert_eq!(chars.r, ' ');
116        assert_eq!(chars.bl, '└');
117        assert_eq!(chars.b, ' ');
118        assert_eq!(chars.br, '┘');
119    }
120
121    #[test]
122    fn barplot_border_chars_match_reference() {
123        let chars = BorderType::Barplot.chars();
124        assert_eq!(chars.tl, '┌');
125        assert_eq!(chars.t, ' ');
126        assert_eq!(chars.tr, '┐');
127        assert_eq!(chars.l, '┤');
128        assert_eq!(chars.r, ' ');
129        assert_eq!(chars.bl, '└');
130        assert_eq!(chars.b, ' ');
131        assert_eq!(chars.br, '┘');
132    }
133
134    #[test]
135    fn border_types_lists_public_variants() {
136        assert_eq!(
137            border_types(),
138            &[BorderType::Barplot, BorderType::Corners, BorderType::Solid]
139        );
140    }
141
142    #[test]
143    fn ascii_border_chars_match_reference() {
144        let chars = BorderType::Ascii.chars();
145        assert_eq!(chars.tl, '+');
146        assert_eq!(chars.t, '-');
147        assert_eq!(chars.tr, '+');
148        assert_eq!(chars.l, '|');
149        assert_eq!(chars.r, '|');
150        assert_eq!(chars.bl, '+');
151        assert_eq!(chars.b, '-');
152        assert_eq!(chars.br, '+');
153    }
154}