Skip to main content

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}