asciigraph/options/charset.rs
1// CharSet — the set of box-drawing characters used to render a data series.
2
3// ---------------------------------------------------------------------------
4// CharSet
5// ---------------------------------------------------------------------------
6
7/// Defines the set of characters used to draw a data series on the graph.
8///
9/// Each field controls a specific part of the line rendering — horizontal
10/// runs, vertical segments, corner arcs, NaN gap caps, axis corners, and
11/// tick marks. Swap out individual characters to change the visual style of
12/// a series without affecting the rendering logic.
13///
14/// Use [`create_char_set`] to create a uniform set where every character is
15/// the same (e.g. `*` or `•`). Use struct update syntax (`..Default::default()`)
16/// to override only the fields you care about while keeping the rest as the
17/// defaults from [`DEFAULT_CHAR_SET`].
18///
19/// # Example
20///
21/// ```rust
22/// use asciigraph::options::CharSet;
23///
24/// // Override only the horizontal and vertical characters.
25/// let partial = CharSet {
26/// horizontal: '=',
27/// vertical_line: '|',
28/// ..Default::default()
29/// };
30/// ```
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32#[derive(Debug, Clone)]
33pub struct CharSet {
34 /// Horizontal line character used for flat segments. Default: `─`
35 pub horizontal: char,
36
37 /// Vertical line character used for steep segments. Default: `│`
38 pub vertical_line: char,
39
40 /// Corner arc going down and to the right (rising series). Default: `╭`
41 pub arc_down_right: char,
42
43 /// Corner arc going down and to the left (falling series). Default: `╮`
44 pub arc_down_left: char,
45
46 /// Corner arc going up and to the right (falling series). Default: `╰`
47 pub arc_up_right: char,
48
49 /// Corner arc going up and to the left (rising series). Default: `╯`
50 pub arc_up_left: char,
51
52 /// End cap drawn at the last finite point before a NaN gap. Default: `╴`
53 pub end_cap: char,
54
55 /// Start cap drawn at the first finite point after a NaN gap. Default: `╶`
56 pub start_cap: char,
57
58 /// Bottom-left corner character for the X-axis. Default: `└`
59 pub up_right: char,
60
61 /// Tick mark character used on the X-axis. Default: `┬`
62 pub down_horizontal: char,
63
64 /// Dashed horizontal character used for threshold lines. Default: `╌`
65 pub dash_horizontal: char,
66
67 /// Dashed horizontal character used for mean annotation. Default: `┄`
68 pub double_dash_horizontal: char,
69
70 /// Heavy dashed horizontal character used for median annotation. Default: `╍`
71 pub heavy_dash_horizontal: char,
72
73 /// Dotted horizontal character used for standard deviation annotation. Default: `·`
74 pub dot_horizontal: char,
75}
76
77impl Default for CharSet {
78 fn default() -> Self {
79 // Delegate to the constant so there is exactly one place where
80 // the actual character values are defined.
81 CharSet {
82 horizontal: DEFAULT_CHAR_SET.horizontal,
83 vertical_line: DEFAULT_CHAR_SET.vertical_line,
84 arc_down_right: DEFAULT_CHAR_SET.arc_down_right,
85 arc_down_left: DEFAULT_CHAR_SET.arc_down_left,
86 arc_up_right: DEFAULT_CHAR_SET.arc_up_right,
87 arc_up_left: DEFAULT_CHAR_SET.arc_up_left,
88 end_cap: DEFAULT_CHAR_SET.end_cap,
89 start_cap: DEFAULT_CHAR_SET.start_cap,
90 up_right: DEFAULT_CHAR_SET.up_right,
91 down_horizontal: DEFAULT_CHAR_SET.down_horizontal,
92 dash_horizontal: DEFAULT_CHAR_SET.dash_horizontal,
93 double_dash_horizontal: DEFAULT_CHAR_SET.double_dash_horizontal,
94 heavy_dash_horizontal: DEFAULT_CHAR_SET.heavy_dash_horizontal,
95 dot_horizontal: DEFAULT_CHAR_SET.dot_horizontal,
96 }
97 }
98}
99
100/// The default box-drawing character set used when no custom [`CharSet`] is provided.
101pub const DEFAULT_CHAR_SET: CharSet = CharSet {
102 horizontal: '─',
103 vertical_line: '│',
104 arc_down_right: '╭',
105 arc_down_left: '╮',
106 arc_up_right: '╰',
107 arc_up_left: '╯',
108 end_cap: '╴',
109 start_cap: '╶',
110 up_right: '└',
111 down_horizontal: '┬',
112 dash_horizontal: '╌',
113 double_dash_horizontal: '┄',
114 heavy_dash_horizontal: '╍',
115 dot_horizontal: '·',
116};
117
118// ---------------------------------------------------------------------------
119// create_char_set
120// ---------------------------------------------------------------------------
121
122/// Creates a [`CharSet`] where every character is set to the same value.
123///
124/// Useful for simple, uniform plot styles such as `*`, `•`, or `#`, where
125/// the distinction between horizontal runs, vertical segments, and arcs is
126/// not important — every position in the series uses the same character.
127///
128/// # Example
129///
130/// ```rust
131/// use asciigraph::options::create_char_set;
132///
133/// let asterisk = create_char_set('*');
134/// let dot = create_char_set('•');
135/// ```
136pub fn create_char_set(character: char) -> CharSet {
137 CharSet {
138 horizontal: character,
139 vertical_line: character,
140 arc_down_right: character,
141 arc_down_left: character,
142 arc_up_right: character,
143 arc_up_left: character,
144 end_cap: character,
145 start_cap: character,
146 up_right: character,
147 down_horizontal: character,
148 dash_horizontal: character,
149 double_dash_horizontal: character,
150 heavy_dash_horizontal: character,
151 dot_horizontal: character,
152 }
153}